Ios 在不同线程上访问NSManagedObject的objectID?
一个对象(CoreData NSManagedObject)的初始访问发生故障,导致UITableViewCell的部分内容创建延迟。这表现在单元格第一次滚动到视图时出现的一个小问题上。我决定将这些对象的访问权转移到后台线程 这就是我实现它的方式,它工作得很好,但是我们都知道我们不应该在另一个线程中访问一个线程(主线程)的NSManagedObjectContext,但是如果一个对象最初是在第一个线程中获取的,我们能在第二个线程中获取它的objectID吗 获取objectID只需要很短的时间,我希望将其与其他内容一起推到后台Ios 在不同线程上访问NSManagedObject的objectID?,ios,core-data,grand-central-dispatch,nsmanagedobject,nsmanagedobjectcontext,Ios,Core Data,Grand Central Dispatch,Nsmanagedobject,Nsmanagedobjectcontext,一个对象(CoreData NSManagedObject)的初始访问发生故障,导致UITableViewCell的部分内容创建延迟。这表现在单元格第一次滚动到视图时出现的一个小问题上。我决定将这些对象的访问权转移到后台线程 这就是我实现它的方式,它工作得很好,但是我们都知道我们不应该在另一个线程中访问一个线程(主线程)的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];
});
}
}
});
这安全吗?或者我必须在主线程中获取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]);
}
}
});
我建议使用
existingObjectWithID:error:
而不是objectWithID:
,因为objectWithID:
将返回一个对象,即使是伪造的对象ID。同意,我剪切并粘贴了原始片段。现在已更新为使用现有ObjectWithId:错误:。