0

iOS COreData アプリで、オブジェクトの編集のみに使用される一時的なコンテキストを試してみました。

iOS 5 で導入された parentContext はバグがあるため破棄したため、メイン コンテキストとマージするための通常の保存通知メカニズムを備えた通常のコンテキストです。

これはうまくいくようですが、ポイントがわかりません:

コントローラーからコントローラーに渡すのではなく、コンテキストを構築するファクトリがあります。一時的なコンテキストは編集目的でのみ機能します。私は常にエンティティを編集しているわけではないため、リソースを解放するために作業が完了したらすぐに削除する必要があると理解しています (おそらく間違っています)。

もう一度仮定すると、一時的なコンテキストを削除する方法は? それとも、後で再利用するために残しておく必要がありますか?

4

2 に答える 2

0

ARC を使用している場合は、MOC を参照しているものがないことを確認するだけです。つまり、どこかにポインターを保持している場合は、nil に設定します。それ以外の場合、参照を停止すると、MOC はすぐに破棄されます。

確認するいくつかの簡単な方法...

  1. インストゥルメントで、MOC オブジェクトをトレースして、割り当て/割り当て解除のタイミングを確認します。

  2. サブクラスNSManagedObjectContext化して、init/dealloc をオーバーライドするだけです。ただし、ARC では、dealloc を除いて、必ず super を呼び出してください。これは機能しません。その後、それを追跡できます

  3. -[NSManagedObjectContext dealloc] にブレークポイントを設定し、それが消えるのを確認します

  4. objc_setAssociatedObjectMOC がいつ割り当て解除されたかを確認できるように、割り当て解除を持つ関連付けられたオブジェクトを ( 経由で) 追加します。

  5. MOC への __weak 参照を設定し、それが nil になるのを観察します

  6. 他の多くのオプション...

要するに、MOC が破壊される (または破壊されない) ことを「追跡」する方法はたくさんあるということです。

ARC を使用している場合は、他のオブジェクトが MOC への参照を保持していないことを確認するだけで、他のすべてのオブジェクトと同様に日没に消えます。

私の一番の提案は、好みで注文した唯一のものです。インストゥルメントの使用方法をすでに知っている場合、これは簡単なことです。

インストゥルメントの使用方法がわからない場合は、間違いなくオプション #1 を使用する必要があります。Apple のプラットフォームで開発するための、より価値のある開発ツール (コンパイラ自体以外) を私は知らないからです。

-- もちろん、ARC を使用しない場合も同じことが当てはまります -- しかし、手動で参照カウントを正しく設定する必要があります。

于 2012-08-31T15:17:34.993 に答える
0

コンテキストの変更を他のコンテキストに伝播する処理を行うこの短いコードを作成しました。

仮定:

@property (nonatomic, strong) NSDictionary* threadsDictionary;

管理対象オブジェクトを取得する方法 (スレッドごと) は次のとおりです。

- (NSManagedObjectContext *) managedObjectContextForThread {

// Per thread, give one back
NSString* threadName = [NSString stringWithFormat:@"%d",[NSThread currentThread].hash];

NSManagedObjectContext * existingContext = [self.threadsDictionary objectForKey:threadName];
if (existingContext==nil){
    existingContext = [[NSManagedObjectContext alloc] init];
    [existingContext setPersistentStoreCoordinator: [self persistentStoreCoordinator]];
    [self.threadsDictionary setValue:existingContext forKey:threadName];
}

return existingContext;

}

グローバルマネージャーの init メソッドのある時点で (私はシングルトンを使用しました):

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backgroundContextDidSave:)                                                    name:NSManagedObjectContextDidSaveNotification                                                   object:nil];

次に、保存通知を受け取り、他のすべてのマネージド コンテキスト オブジェクトに伝播します。

- (void)backgroundContextDidSave:(NSNotification *)notification {
    /* Make sure we're on the main thread when updating the main context */
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
                               withObject:notification
                            waitUntilDone:NO];
        return;
    }

    /* merge in the changes to the main context */
    for (NSManagedObjectContext* context in [self.threadsDictionary allValues]){
            [context mergeChangesFromContextDidSaveNotification:notification];
    }
}

(わかりやすくするために、他のいくつかのメソッドは削除されています)

于 2012-08-31T15:18:09.283 に答える