【发布时间】:2013-05-03 16:31:58
【问题描述】:
我的应用中有一个表格视图,其中包含一个 NSFetchedResultsController 以加载到一些 CoreData 对象中。
随着表格在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];
}
如您所见,如果您在 _scannedSites 中还没有任务的 UserSite 信息,则会启动一个后台线程,获取该任务的 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];
}
【问题讨论】:
标签: ios multithreading core-data uitableview gdc