いくつかの CoreData オブジェクトにロードする NSFetchedResultsController を含むテーブルビューをアプリに持っています。
テーブルが に組み込まれcellForRowAtIndexPath:
ているため、セルごとにフェッチを実行して、別のオブジェクトから他の情報を取得する必要があります。
テーブルは UserTasks で満たされているため、UserSite から情報を取得する必要があります (UserTask には siteID 属性が含まれています)。
バックグラウンド スレッドで UserSite 情報を取得し、一時的なコンテキストを使用しています。正常に動作しますが、スクロール時に UI を少し遅らせたいと考えています。
Site *site = [_scannedSites objectForKey:task.siteID];
if(!site)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
AppDelegate *ad = [AppDelegate sharedAppDelegate];
NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
temporaryContext.persistentStoreCoordinator = ad.persistentStoreCoordinator;
Site *site2 = [task getSiteWithContext:temporaryContext];
if(site2)
{
[ad.managedObjectContext performBlock:^{
Site *mainContextObject = (Site *)[ad.managedObjectContext objectWithID:site2.objectID];
[_scannedSites mainContextObject forKey:task.siteID];
}];
dispatch_async(dispatch_get_main_queue(), ^{
Site *newSite = [_scannedSites objectForKey:task.siteID];
cell.lblCustName.text = newSite.siteName;
cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", newSite.siteAddressLine1, newSite.siteCity, newSite.siteState];
cell.lblPhone.text = [self formatPhoneNum:newSite.phone];
});
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
cell.lblCustName.text = @"";
cell.lblAddr.text = @"";
cell.lblPhone.text = @"";
});
}
});
}
else
{
cell.lblCustName.text = site.siteName;
cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", site.siteAddressLine1, site.siteCity, site.siteState];
cell.lblPhone.text = [self formatPhoneNum:site.phone];
}
ご覧のとおり、タスクの UserSite 情報が にまだない場合は_scannedSites
、バックグラウンド スレッドが開始され、そのタスクの UserSite が取得されて保存され、メイン スレッドで詳細が入力されます。
私が言ったように、スクロールするときにかなり迷惑なラグがあります...バックグラウンドで作業を行うことで回避したかったのです。
私はこれについて間違った方法で進んでいますか?
ありがとう、アドバイスをいただければ幸いです。
編集
CoreData でリレーションシップを作成し、現在それを使用していcellForRowAtIndexPath
ます。まだ存在しない場合は、作成します。これははるかにうまく機能しています。
Site *site = task.site;
if(!site)
{
AppDelegate *ad = [AppDelegate sharedAppDelegate];
NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
temporaryContext.persistentStoreCoordinator = ad.persistentStoreCoordinator;
[temporaryContext performBlock:^{
Site *tempContextSite = [task getSiteWithContext:temporaryContext];
[ad.managedObjectContext performBlock:^{
Site *mainManagedObject = (Site *)[ad.managedObjectContext objectWithID:tempContextSite.objectID];
task.site = mainManagedObject;
NSError *error;
if (![temporaryContext save:&error])
{
}
[ad.managedObjectContext performBlock:^{
NSError *e = nil;
if (![ad.managedObjectContext save:&e])
{
}
dispatch_async(dispatch_get_main_queue(), ^{
cell.lblCustName.text = mainManagedObject.siteName;
cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", mainManagedObject.siteAddressLine1, mainManagedObject.siteCity, mainManagedObject.siteState];
cell.lblPhone.text = [self formatPhoneNum:mainManagedObject.phone];
});
}];
}];
}];
}
else
{
cell.lblCustName.text = site.siteName;
cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", site.siteAddressLine1, site.siteCity, site.siteState];
cell.lblPhone.text = [self formatPhoneNum:site.phone];
}