2011-11-29 6 views
56

iOS5では本当に簡単なのですか?新しいNSPrivateQueueConcurrencyTypeを介したコアデータのバックグラウンドフェッチ

私は背景が私のAppDelegateでこのコードを使用してフェッチを実行するために使用:

dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL); 
dispatch_async(downloadQueue, ^{ 
     self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.managedObjectContext]; 
     [self.myDownloadClass download]; 
    }); 

dispatch_release(downloadQueue); 

マイダウンロードクラスは、いくつかのXMLデータをフェッチするためにNSURLConnectionを行い、データを解析するためにNSXMLParserを使用して、複雑なスキーマを更新コアデータです。コアデータを実際に更新するには、常にメインスレッドに切り替えます。設定するには、私のAppDelegate内の他のコードを少し変更に伴い

NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
[child setParentContext:self.managedObjectContext]; 

[child performBlock:^{ 
    self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child]; 
    [self.myDownloadClass download]; 
    }]; 

:(dispatch_get_main_queueを()dispatch_syncの呼び出しのたくさんの厄介なコード、....

私の新しいコードは次のようになりますNSMainQueueConcurrencyTypeに親モデルオブジェクトのコンテキストタイプ:

- (NSManagedObjectContext *)managedObjectContext 
{ 
    if (__managedObjectContext != nil) 
    { 
     return __managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    if (coordinator != nil) 
    { 
     __managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
     [__managedObjectContext setPersistentStoreCoordinator:coordinator]; 
    } 
    return __managedObjectContext; 
} 

非常にうまく動作するようです全体の更新プロセスはまだ別のスレッドで実行されますが、私はスレッドを作成する必要はありませんでした魔法のように思える

。。。

物理コアデータファイルに変更をコミットするかどうかを覚えておいてください。親コンテキストでもsave:を呼び出す必要があります。

私は本当にここで質問しませんでした。私はこれを投稿していますので、他の人に役立つようにしました。新しいiOS5管理オブジェクトコンテキストメソッドを検索するときに見つけたものはすべて、コード例なしで高レベルの詳細しか提供しなかったためです。それをpre-iOS5で行う方法について話し合う。

+0

本当に簡単ですか? – timthetoolman

+0

共有ありがとう! – Max

+0

その後、変更を保存する必要があります –

答えて

0

この新しいAPIの実装方法を理解しようとしています。 NSOperation通常

が、この例ではdispatch_asyncを使用して簡素化:マルチスレッドコアデータのための私のいつものパターンは、このようなものである

dispatch_queue_t coredata_queue; // some static queue 

dispatch_async(coredata_queue, ^() { 
    // get a new context for this thread, based on common persistent coordinator 
    NSManagedObjectContext *context = [[MyModelSingleton model] threadedContext]; 

    // do something expensive 

    NSError *error = nil; 
    BOOL success = [context save:&error]; 
    if (!success) { 
     // the usual. 
    } 

    // callback on mainthread using dispatch_get_main_queue(); 
}); 

そして、メインスレッドはマージするNSManagedObjectContextDidSaveNotificationに基づいてUIを更新することで応答します主な文脈

新しいAPIは、このパターンのラッパーであるように見えます。childのコンテキストは、永続コーディネーターを親のコンテキストから新しいコンテキストを作成するようなものに見えます。 initでNSPrivateQueueConcurrencyTypeと指定すると、performBlockパラメータがプライベートキューで実行されていることが確認されます。

新しいAPIは入力するコードがそれほど少なくないようです。 '伝統的な'スレッディングよりも利点はありますか?

2

はい - これは本当に簡単です(iOS 5.0)。 iOS 4との互換性のために、これまでのハードルは残っていますが、ドキュメンテーションはスレッドの制限であまりにも悪くはありません。 Wikiセクションにこれを追加する必要がありますか?

関連する問題