菜鸟教程小白 发表于 2022-12-12 19:17:28

ios - NSManagedObjectContext - 当 parent 改变时如何更新 child ?


                                            <p><p>Apple 文档不清楚(或者我找不到)当 parentMOC 插入后保存时在父子 MOC 的情况下会发生什么。 </p>

<p>我正在使用 MARCUS ZARRA 的 <a href="http://martiancraft.com/blog/2015/03/core-data-stack/" rel="noreferrer noopener nofollow">http://martiancraft.com/blog/2015/03/core-data-stack/</a>方法,顶部有一个 privateQMOC,childMainMOC 作为主线程之一。 </p>

<p><em>问题</em></p>

<p>我通过在 privateMOC 上调用 save 的后台 Internet 请求将 10,000 个对象添加到 privateMOC,但任何基于 childMainMOC 上下文构建的 NSFetchedResultsController 在父级保存后都不会调用我的委托(delegate)。因此界面不会更新以显示 parentMOC 中的更改。</p>

<p>我想调用一些东西来更新 childMainMOC 中的所有对象 - 然后应该调用子 Controller 上的委托(delegate)方法。</p>

<p>或其他一些解决方案。 </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>好的 - 所以我想通了。 </p>

<p>模型如下:
马库斯·扎拉的 <a href="http://martiancraft.com/blog/2015/03/core-data-stack/" rel="noreferrer noopener nofollow">http://martiancraft.com/blog/2015/03/core-data-stack/</a>
privateMOC 位于根目录,这允许更好的性能,并且出于其他原因也需要这种方式。我只使用了 2 个 MOC:私有(private)根一个和子一个,它是一个主线程。</p>

<p>然后阅读:
基本上,他解释了 Core Data 如何处理通知等。
<a href="http://benedictcohen.co.uk/blog/archives/308" rel="noreferrer noopener nofollow">http://benedictcohen.co.uk/blog/archives/308</a> </p>

<p>那么 - 我需要做的最后一件事是:确保程序中的所有 objectID 都是真正永久的。 </p>

<pre><code>- (id)insertNewObjectForEntityName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context {

NSManagedObject *object = ;

// Make sure all inserted objects have a permanent ID.
// THIS IS VITAL. Without getting the permanentIDs, changes that come in from the web will not propogate to the child mainQ MOC and the UI will not update.
// Tested to be performant.
//NSLog(@&#34;testing this - object.objectID is a temp now I think: %@ isTemp:%d&#34;, object.objectID, (int) );
// http://stackoverflow.com/questions/11990279/core-data-do-child-contexts-ever-get-permanent-objectids-for-newly-inserted-obj
NSError* error = nil;
error:&amp;error];
if (error || )
    NSLog(@&#34;obtainPermanentIDsForObjects is NOT WORkING - FIX: a new %@ isTemp: %d !!&#34;, entityName, (int) );

return object;
</code></pre>

<p>}</p>

<p>我还需要按照 Benedicts 的文章 - 监听父根私有(private) MOC 中的更改</p>

<pre><code>/// . http://benedictcohen.co.uk/blog/archives/308good info !
/// I need this firing as sometimes objects change and the save notification below is not enough to make sure the UI updates.
- (void)privateQueueObjectContextDidChangeNotification:(NSNotification *)notification {
    NSManagedObjectContext *changedContext = notification.object;
    NSManagedObjectContext *childContext = self.mainQueueObjectContext;
    BOOL isParentContext = childContext.parentContext == changedContext;
    if (!isParentContext) return;

    //Collect the objectIDs of the objects that changed
    __block NSMutableSet *objectIDs = ;
    [changedContext performBlockAndWait:^{
      NSDictionary *userInfo = notification.userInfo;
      for (NSManagedObject *changedObject in userInfo) {
            ;
      }
      for (NSManagedObject *changedObject in userInfo) {
            ;
      }
      for (NSManagedObject *changedObject in userInfo) {
            ;
      }      
    }];

    //Refresh the changed objects
    [childContext performBlock:^{
      for (NSManagedObjectID *objectID in objectIDs) {
            NSManagedObject *object = ;
            if (object) {
                ;
                //NSLog(@&#34;refreshing %@&#34;, );
            }
      }
    }];
}
   - (void)privateQueueObjectContextDidSaveNotification:(NSNotification *)notification {
    //NSLog(@&#34;private Q MOC has saved&#34;);
    [self.mainQueueObjectContext performBlock:^{
      ;
      // I had UI update problems which I fixed with mergeChangesFromContextDidSaveNotification along with obtainPermanentIDsForObjects: in the insertEntity call.
    }];
</code></pre>

<p>}</p>

<pre><code>    /// When the MainMOC saves - the user has changed data.
/// We save up into the privateQ as well at this point.
- (void)mainQueueObjectContextDidSaveNotification:(NSNotification *)notification {
    NSLog(@&#34;main Q MOC has saved - UI level only changes only please&#34;);
    [self.privateQueueObjectContext performBlock:^{
      NSError* error = nil;
      if (self.privateQueueObjectContext.hasChanges) {
            ;
            if (error)
            {
                NSLog(@&#34;Save up error - the actual datastore was not updated : %@&#34;, error);
            }
      } else {
            //NSLog(@&#34;No need to save&#34;);
      }
    }];
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - NSManagedObjectContext - 当 parent 改变时如何更新 child ?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/36338135/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/36338135/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - NSManagedObjectContext - 当 parent 改变时如何更新 child ?