mah*_*udz 3 core-data grand-central-dispatch nsmanagedobject nsmanagedobjectcontext ios
我的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];
});
}
}
});
Run Code Online (Sandbox Code Playgroud)
这样安全吗?或者我必须在mainThread中获取objectID吗?
在线程之间传递托管对象的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]);
}
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1617 次 |
| 最近记录: |