在 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的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发系列-NSOperation

多线程-NSOperation

7 SDImageCache

iOS多线程---NSOperation介绍和使用

ios多线程 -- NSOperation 简介

多线程 NSOperation