Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 多线程核心数据-NSManagedObject无效_Ios_Core Data_Nsmanagedobject_Nsmanagedobjectcontext_Invalidation - Fatal编程技术网

Ios 多线程核心数据-NSManagedObject无效

Ios 多线程核心数据-NSManagedObject无效,ios,core-data,nsmanagedobject,nsmanagedobjectcontext,invalidation,Ios,Core Data,Nsmanagedobject,Nsmanagedobjectcontext,Invalidation,正如标题所示,我正在使用一个核心数据应用程序,该应用程序在不同的后台线程中填充对象(XML解析) 在我的背景线程中,我正在这样做 managedContext = [[NSManagedObjectContext alloc] init]; [managedContext setUndoManager:nil]; [managedContext setPersistentStoreCoordinator: [[DataManager sharedManager] persistentStore

正如标题所示,我正在使用一个核心数据应用程序,该应用程序在不同的后台线程中填充对象(XML解析)

在我的背景线程中,我正在这样做

managedContext = [[NSManagedObjectContext alloc] init];
[managedContext setUndoManager:nil];

[managedContext setPersistentStoreCoordinator: [[DataManager sharedManager] persistentStoreCoordinator]];

 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
 [nc addObserver:self
        selector:@selector(mergeChanges:)
            name:NSManagedObjectContextDidSaveNotification
          object:managedContext];


NSMutableArray *returnSource = [[self parseDocument:doc] retain];


 [managedContext save:&error];

 if (error) {
     NSLog(@"saving error in datafeed"); 
 }

 [managedContext reset];

[self performSelectorOnMainThread:@selector(parseCompleteWithSource:) withObject:returnSource waitUntilDone:YES];
合并方法如下所示:

NSManagedObjectContext *mainContext = [[DataManager sharedManager] managedObjectContext];

// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                              withObject:notification
                           waitUntilDone:YES];  

[[NSNotificationCenter defaultCenter] removeObserver:self];
我认为合并是成功的,但当我想在UITableView中显示它时,它总是告诉我我的对象无效,这是因为

[managedContext reset];
我想做的是在后台显示数据库中当前的项目,解析xml,如果完成了,我想用新的/更新的对象更新UITableView。我该怎么做呢?我能以某种方式将对象“更新”到另一个上下文中吗?或者合并不能正常工作吗

我是否需要在主ObjectContext中定义特定的内容? 我尝试过不同的合并政策,但没有任何运气


希望你能帮助我,谢谢

在这种情况下,没有理由在后台上下文中调用
reset
,因为它将随后台线程一起消失,并且您在任何情况下都不会再次使用它。当您希望上下文忘记前面的步骤时,通常使用带有撤消管理的
reset

这里的主要问题是后台线程被配置为从它创建的托管对象上下文接收通知。这是毫无意义的


相反,您需要注册tableview控制器(在前线程上),以从后台线程上的上下文接收
NSManagedObjectContextDidSaveNotification
。这样,当后台上下文保存时,前/主上下文将使用新数据更新自身,这将触发tableview的更新

在这种情况下,没有理由在后台上下文中调用
reset
,因为它将随后台线程一起消失,并且您在任何情况下都不会再次使用它。当您希望上下文忘记前面的步骤时,通常使用带有撤消管理的
reset

这里的主要问题是后台线程被配置为从它创建的托管对象上下文接收通知。这是毫无意义的


相反,您需要注册tableview控制器(在前线程上),以从后台线程上的上下文接收
NSManagedObjectContextDidSaveNotification
。这样,当后台上下文保存时,前/主上下文将使用新数据更新自身,这将触发tableview的更新

我相信您的问题在于
returnSource
数组的内容。如果这是一组
NSManagedObject
实例,那么它们将由后台线程上下文在后台线程上创建

调用
-[NSManagedObjectContext reset]
将使它们无效,因为这是您明确告诉上下文要做的事情。但这不是大问题

然后,继续将数组发送到主线程,通过线程边界传递
NSManagedObject
实例,在上下文之间传递是一个很大的禁忌

您需要做的是:

  • 使用
    NSManagedObject
    NSManagedObject
    s创建一个数组
  • 通过线程边界发送对象ID数组
  • 从具有上下文的新线程上的托管对象ID,使用
    NSManagedObject
    s重新创建一个数组
  • 我已经做了一些核心数据助手,遵循三条规则(第三次写东西时,要把它概括起来)

    最重要的是,我隐藏了为每个线程管理不同托管对象上下文、处理通知以及所有垃圾的复杂性。相反,我引入了线程本地上下文的概念。基本上是延迟创建的
    NSManagedObjectContext
    实例,在当前线程退出时自动注册更新和清理

    正常用例:

    NSManagedObjectCotext* context = [NSManagedObjectCotext threadLocalContext];
    // Do your stuff!!
    NSError* error = nil;
    if (![context saveWithFailureOption:NSManagedObjectContextCWSaveFailureOptionThreadDefault 
                                  error:&error]) 
    {
        // Handle error.
    }
    

    完整的源代码,包括一个示例应用程序,用于解析apple.com上的新闻RSS并将其存储在核心数据中,可在此处找到:。

    我认为您的问题在于
    returnSource
    数组的内容。如果这是一组
    NSManagedObject
    实例,那么它们将由后台线程上下文在后台线程上创建

    调用
    -[NSManagedObjectContext reset]
    将使它们无效,因为这是您明确告诉上下文要做的事情。但这不是大问题

    然后,继续将数组发送到主线程,通过线程边界传递
    NSManagedObject
    实例,在上下文之间传递是一个很大的禁忌

    您需要做的是:

  • 使用
    NSManagedObject
    NSManagedObject
    s创建一个数组
  • 通过线程边界发送对象ID数组
  • 从具有上下文的新线程上的托管对象ID,使用
    NSManagedObject
    s重新创建一个数组
  • 我已经做了一些核心数据助手,遵循三条规则(第三次写东西时,要把它概括起来)

    最重要的是,我隐藏了为每个线程管理不同托管对象上下文、处理通知以及所有垃圾的复杂性。相反,我引入了线程本地上下文的概念。基本上是延迟创建的
    NSManagedObjectContext
    实例,在当前线程退出时自动注册更新和清理

    正常用例:

    NSManagedObjectCotext* context = [NSManagedObjectCotext threadLocalContext];
    // Do your stuff!!
    NSError* error = nil;
    if (![context saveWithFailureOption:NSManagedObjectContextCWSaveFailureOptionThreadDefault 
                                  error:&error]) 
    {
        // Handle error.
    }
    

    完整的源代码,包括用于解析apple.com上的新闻RSS并将其存储在核心数据中的示例应用程序,可在此处找到:。

    -1虽然您的代码可能有用,但它并不能真正解决此特定问题。嘿!谢谢,我自己想出了这个办法,并且完全按照你在这里描述的做了。:)我也有同样的问题,你能解释一下如何获取NSManagedObjects数组吗?请重置无效-“这是可能的。”