【问题标题】:How do I create a child NSManagedObjectContext?如何创建子 NSManagedObjectContext?
【发布时间】:2012-08-29 14:01:14
【问题描述】:

我看到一些视频/主题说可以创建“子”MOC - 使用其他 MOC 作为其持久存储的 MOC。例如,在您为应用程序线程化并希望拥有一个可以保存/回滚子线程创建的更改的单一主 MOC 的上下文中很有用。 (据我了解,MOC 和它的 managedObjects 必须都在同一个线程上使用)

问题是,如何创建子 MOC?我无法追踪我正在观看的介绍它们的 WWDC 视频,我所看到的一切都在谈论如何在它们制作完成后使用它们。我可以轻松分配一个新的 MOC,但我该如何设置它持久存储成为另一个 MOC?参考没有显示任何功能!

【问题讨论】:

    标签: objective-c ios xcode core-data nsmanagedobjectcontext


    【解决方案1】:

    创建一个您可以完全控制同步的新 MOC。这与调用 init 相同,与前父/子关系的行为相同。

    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
           initWithConcurrencyType:NSConfinementConcurrencyType];
    

    通过设置 MOC 的属性,您可以将 MOC 设置为另一个 MOC:

    moc.parentContext = someOtherMocThatIsNowMyParent;
    

    在这里,孩子选择父母。我确定我的孩子希望他们是 NSManagedObjectContexts。父上下文必须是 NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType

    您可以创建一个“绑定”到私有队列的 MOC:

    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
           initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    

    这意味着您只能通过performBlockperformBlockAndWait API 访问它。您可以从任何线程调用这些方法,因为它们将确保块中代码的正确序列化。比如……

    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
           initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    moc.parentContext = someOtherMocThatIsNowMyParent;
    [moc performBlock:^{
        // All code running in this block will be automatically serialized
        // with respect to all other performBlock or performBlockAndWait
        // calls for this same MOC.
        // Access "moc" to your heart's content inside these blocks of code.
    }];
    

    performBlockperformBlockAndWait 之间的区别在于performBlock 将创建一个代码块,并使用Grand Central Dispatch 安排它在未来某个时间在某个未知线程上异步执行。方法调用会立即返回。

    performBlockAndWait 将与所有其他 performBlock 调用进行一些神奇的同步,并且当在此之前出现的所有块都完成时,该块将执行。调用线程将挂起,直到此调用完成。

    您还可以创建一个“绑定”到主线程的 MOC,就像私有并发一样。

    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
           initWithConcurrencyType:NSMainQueueConcurrencyType];
    moc.parentContext = someOtherMocThatIsNowMyParent;
    [moc performBlock:^{
        // All code running in this block will be automatically serialized
        // with respect to all other performBlock or performBlockAndWait
        // calls for this same MOC.  Furthermore, it will be serialized with
        // respect to the main thread as well, so this code will run in the
        // main thread -- which is important if you want to do UI work or other
        // stuff that requires the main thread.
    }];
    

    这意味着只有当你知道你在主线程上时,你才应该直接访问它,通过performBlockperformBlockAndWait API。

    现在,您可以通过performBlock 方法使用“主并发”MOC,或者直接如果您知道自己已经在主线程中运行。

    【讨论】:

    • 感谢您提供如此详尽的回答。
    • 你好,我知道它真的很老了,但我的问题还不足以创建一个新的,我想知道我应该在上下文的哪里调用 save ,在 performBlock 内部还是外部?谢谢!
    • 感谢您的出色回答。它帮助了我,因为 Apple 的文档声称 parentContext 是“只读的”,但显然不是。 developer.apple.com/library/prerelease/ios/documentation/Cocoa/…
    【解决方案2】:

    然后初始化子 MOC:

    [_childMOC performBlockAndWait:^{
                [_childMOC setParentContext:parentMOC]; 
     }];
    

    【讨论】:

    • 所以...我可以跨线程访问 MOC,只是不允许跨线程操作(插入、删除、保存、回滚)?
    • 您可以从其他线程调用 performBlock 和 performBlockAndWait。其他不多。
    猜你喜欢
    • 2019-09-26
    • 2011-04-05
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多