0

私は新しいiOS開発者です。助けを願っています。多くのNSManagedObjectを作成できるようにしたいと思います。1つのNSManagedObjectのフィールドのサイズは約5Mbです。こんなに大量のメモリをiPhoneのメモリに保存できませんでした。そして、それをデータベースに保存したいと思います。しかし、NSManagedObjectを保存すると、メモリ内に残ります。これは、約20個のオブジェクトを保存すると、メモリ警告が表示され、アプリケーションがクラッシュするためです。これが私のコードです

- (void)SaveItem
    {
        NSString *entityName = kEntityName;
        AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        NSManagedObjectContext *context = appDelegate.managedObjectContext;
        NSEntityDescription *entityDesctiption = [NSEntityDescription 
                                                  entityForName: entityName
                                                  inManagedObjectContext:context];
        // check if town exists
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id == %d", self.imageID];
        NSFetchRequest *requestToCheckExistense = [[NSFetchRequest alloc] init];
        [requestToCheckExistense setEntity:entityDesctiption];
        [requestToCheckExistense setPredicate:predicate];
        NSArray *objects = [context executeFetchRequest:requestToCheckExistense error:nil];
        [requestToCheckExistense release];
        if (objects == nil)
        {
            NSLog(@"there was an error");
        }
        NSManagedObject *object;
        if ([objects count] > 0)
        {
            // edit item
            object = [objects objectAtIndex:0];
        }
        else
        {
            // if object doesn't exist, find max id to imlement autoincrement
            NSFetchRequest *request = [[NSFetchRequest alloc] init];
            [request setEntity:entityDesctiption];
            request.propertiesToFetch = [NSArray arrayWithObjects: @"id", nil];
            NSArray *allobjects = [context executeFetchRequest:request error:nil];
            [request release];
            NSInteger newID = 1;
            if ([allobjects count] > 0)
            {
                NSNumber *maxID = [allobjects valueForKeyPath:@"@max.id"];
                newID = [maxID intValue] + 1;
            }

            // write item
            object = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context]; 
            [object setValue:[NSNumber numberWithInt:newID] forKey:@"id"];
            self.imageID = newID;
        }
        // fill NSManagedObject
        // size of objNSData is about 5MB
        NSMutableData *objNSData = [[DatabaseManager sharedDatabaseManager] encryptedDataFromImage:bigImage];
        [object setValue:objNSData forKey:@"big"];

         [context save:nil];
     }

[self SaveItem]を20回呼び出そうとすると、アプリがクラッシュしてメモリ警告が表示されます。コメントしたとき

[object setValue:objNSData forKey:@"big"];

すべてが大丈夫だった。

@autoreleasepoolにコードを追加しようとしましたが、役に立ちませんでした。

データをデータベースに保存しても、iPhoneのメモリに残っていることはわかっています。このメモリからそれを解放する方法は?管理対象オブジェクトのセットを取得すると、それらはメモリにありません(100個のオブジェクトを簡単に取得でき、それぞれに5Mbフィールドがあります)

4

1 に答える 1

3

画像(または大きなバイナリ値)をコアデータに保存することは適切なオプションではありません。Appleはそれに反対することをお勧めします。そのためのルールがあります。この他の質問/回答を確認してください。

オブジェクトをメモリから取り出したい場合は、オブジェクトに対するすべての参照を削除する必要があります。タイトループで「SaveItem」を実行している場合は、ループ自体ではなく、すべてのループ実行を自動解放プールでラップする必要があります。

アップルのドキュメントから、それもあなたの問題かもしれません:

保留中の変更(挿入、削除、または更新)がある管理対象オブジェクトは、コンテキストにsave:、reset、rollback、deallocメッセージ、または変更を元に戻すための適切な数の取り消しが送信されるまで、コンテキストによって保持されます。コンテキストに関連付けられた元に戻るマネージャーは、変更された管理対象オブジェクトを保持します。デフォルトでは、コンテキストの取り消しマネージャーは無制限の取り消し/やり直しスタックを保持します。アプリケーションのメモリフットプリントを制限するには、必要に応じて、コンテキストのUNDOスタックを(removeAllActionsを使用して)スクラブするようにしてください。コンテキストのUNDOマネージャーを保持しない限り、コンテキストの割り当てが解除されます。

Core Dataの取り消し機能を使用する予定がない場合は、コンテキストの取り消しマネージャーをnilに設定することで、アプリケーションのリソース要件を減らすことができます。これは、バックグラウンドワーカーのスレッドだけでなく、大規模なインポートまたはバッチ操作にも特に役立ちます。

于 2012-06-05T11:34:01.143 に答える