在 NSOperation 中查找 NSManagedObject
Posted
技术标签:
【中文标题】在 NSOperation 中查找 NSManagedObject【英文标题】:Finding NSManagedObject inside of NSOperation 【发布时间】:2015-07-10 21:37:44 【问题描述】:鉴于objectID
,我认为[moc existingObjectWithID:self.objectID error:&error]
是在线程内查找现有对象的正确方法,但我无法让它工作,为什么?
背景/代码
我有一个 NSManagedObject
已保存。我可以在主线程上看到它的所有属性。我在自定义init
方法中将对象传递给我的NSOperation
,在该方法中,我正在保存它的objectID
:
- (instancetype)initWithEntity:(NSManagedObject *)object
self = [super init];
if (self)
self.objectID = object.objectID;
...
return self;
然后在我的操作的main
函数中,我正在查找我的对象以便我可以使用它。
- (void)main
if (self.isCancelled) return;
NSManagedObjectContext *moc = [NSManagedObjectContext MR_context];
NSError *error = nil;
self.object = [moc existingObjectWithID:self.objectID error:&error];
if (error)
DDLogError(@"error finding object: %@", error);
...
MR_context
是一个 MagicalRecord 方法,它简单地设置一个并发类型为 NSPrivateQueueConcurrencyType
的新上下文,其父级设置为根保存上下文。所有这些在我看来都是正确的。
错误
当没有设置调试器时,我只需为对象获取一个fault
。如果我尝试查找它的任何属性,我会得到nil
。
打开调试器并设置-com.apple.CoreData.ConcurrencyDebug 1
时出现一些错误:
在模拟器中,EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, subcode=0x0)
位于 [moc existingObjectWithID:self.objectID error:&error]
行。
在设备上,我在同一行得到以下信息:
CoreData`+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:
-> 0x185946614 <+0>: brk #0x1
所以很明显出了点问题,但objectID
不是临时的,它与我在主线程上检查真实对象时看到的objectID
相同。所以我不确定为什么它不起作用。
我也试过了:
self.object = [moc objectWithID:self.objectID];
但这也不起作用。有什么想法吗?
更新
2015-07-10 - 好的,如果我使用带有 moc
的块,那么我可以从该块中正确访问该对象。
[moc performBlock:^
NSError *error = nil;
NSManagedObject *o = [moc existingObjectWithID:self.objectID error:&error];
];
如何正确提取该对象,以便可以在操作正在运行的线程中访问它?执行__block
属性,然后将其设置在块中并在块外使用它失败。
context 的设置方式是否存在问题?
【问题讨论】:
您提到它不是临时 ID - 只是检查您是否通过在 objectID 上调用isTemporaryID
进行测试?
是的,我做到了。对不起,我应该回来回答这个问题。我现在就这样做。
【参考方案1】:
MagicalRecord 的上下文设置了自己的队列来对其执行操作。因此,如果您想使用它来查找某些内容,则必须在一个块中进行([context performBlock:]
或[context performBlockAndWait:]
),以便它可以在自己的队列中执行它,然后返回到NSOperation
。
我最终做的是创建一对__block
属性,然后从块外的对象中提取所需的内容。
【讨论】:
以上是关于在 NSOperation 中查找 NSManagedObject的主要内容,如果未能解决你的问题,请参考以下文章