我的UITableViewCell内容创建的一部分因一个对象(CoreData NSManagedObject)初始访问时发生的错误而延迟。这表现在一个小的打嗝,细胞首先滚动到视图中。我决定将这些对象的访问权限推送到后台线程。
这是我实现它的方式并且它运行良好,但是我们都知道我们不应该在另一个线程中访问一个线程(主线程)的NSManagedObjectContext,但是我们可以在一个线程中获取一个对象的objectID第二个线程,如果它最初是在第一个线程中获取的?
获取objectID需要花费少量时间,我希望将其他所有内容都推到后台。
MyRecord *record = [self.frc objectAtIndexPath: indexPath];
// Should the following be here or can it be below in the background thread?
// NSManagedObjectID *recordObjectID = record.objectID;
dispatch_async(_recordViewQueue, ^(void) {
if ([cell.origIndexPath isEqual:indexPath]) {
// should the following be here or above? It works here, but am I just lucky?
// this call seems to take about 2/100 of a second
NSManagedObjectID *recordObjectID = record.objectID;
NSManagedObjectContext *bgndContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
bgndContext.persistentStoreCoordinator = App.sharedApp.storeCoordinator;
MyRecord *newRecord = (MyRecord *) [bgndContext objectWithID:recordObjectID];
[self updateCell:cell withRecord:newRecord];
if ([cell.origIndexPath isEqual:indexPath]) {
dispatch_async(dispatch_get_main_queue(), ^{
[(UIView*) cell.recordView setNeedsDisplay];
});
}
}
});
这样安全吗?或者我必须在mainThread中获取objectID吗?
答案 0 :(得分:5)
在线程之间传递托管对象的objectID是安全的。在线程之间使用托管对象是不安全的。使用objectID和线程的托管对象上下文来调用existingObjectWithID:error:获取该线程的托管对象的实例。
我会更新你的代码:
MyRecord *record = [self.frc objectAtIndexPath: indexPath];
NSManagedObjectID *recordObjectID = record.objectID;
dispatch_async(_recordViewQueue, ^(void) {
if ([cell.origIndexPath isEqual:indexPath]) {
NSManagedObjectContext *bgndContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
bgndContext.persistentStoreCoordinator = App.sharedApp.storeCoordinator;
NSError * error = nil;
MyRecord *newRecord = (MyRecord *) [bgndContext existingObjectWithID:recordObjectID error:&error];
if (newRecord) {
[self updateCell:cell withRecord:newRecord];
if ([cell.origIndexPath isEqual:indexPath]) {
dispatch_async(dispatch_get_main_queue(), ^{
[(UIView*) cell.recordView setNeedsDisplay];
});
}
}
else {
NSLog(@"unable to find existing object! error: %@ (userInfo: %@)", [error localizedDescription], [error userInfo]);
}
}
});