代码之家  ›  专栏  ›  技术社区  ›  cpjolicoeur

核心数据后台同步冲突问题

  •  0
  • cpjolicoeur  · 技术社区  · 14 年前

    我在开发带有核心数据的iPhone应用程序时遇到了崩溃问题。

    应用程序将数据与后台线程上的Web服务同步。

    当应用程序首次启动时,核心数据数据库中的现有数据将在UITableView中显示给用户,同时启动后台线程从web服务API获取最新数据。让我们调用核心数据模型User和Items,只是为了与拥有许多项的用户进行讨论。这些项是UITableView中显示的内容。

    当API结果返回时,将从核心数据中删除用户现有的项记录,并将新的项记录集插入核心数据中。解析完所有项后,会将一条消息发送回主线程,以合并核心数据更改并从CD中重新提取数据。

    但是,我在configure table cell例程中不断崩溃,我确信这是因为超出范围的对象。也就是说,主线程试图显示核心数据中的对象,而后台线程则从核心数据中删除那些相同的对象,并用新对象替换它们。

    处理此类冲突的最佳方法是什么?我是否必须加入某种机制,在主视图加载/显示其所有数据之前不启动后台线程更新?如果是的话,我该如何做到这一点?我是否仍能保持相同的方法,并更好地处理显示项的删除?

    6 回复  |  直到 14 年前
        1
  •  1
  •   falconcreek    14 年前

    请参阅TopSongs项目SongsViewController实现 明确地 viewDidLoad handleSaveNotification

    - (void)handleSaveNotification:(NSNotification *)aNotification {
    [managedObjectContext mergeChangesFromContextDidSaveNotification:aNotification];
    [self fetch];
    }
    

    您的viewController handleSaveNotification:

    替换:

    // ViewController.m viewDidLoad
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
    

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:nil];
    

    // ViewController.m viewDidUnload
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
    

    使用:

    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:nil];
    
        2
  •  0
  •   Eiko    14 年前

        3
  •  0
  •   paxswill    14 年前

    如何访问表的数据?如果你用的是 NSFetchedResultsController ,它应该以安全的方式自动更新单元格。

    在原问题的范围内:
    除非数据保存在其他地方,否则在表格中滚动时重新绘制单元格将访问数据。你呢 能够 复制用于填充单元格的所有数据,但这会增加内存使用量。

        5
  •  0
  •   TechZen    14 年前

    检查NSFetchedResultsControllerDelegate方法 controllerWillChangeContent: controllerDidChangeContent: .

    您有责任通知表您将使用 beginUpdates endUpdates 信息。当获取的结果控制器要修改返回的数据时,表需要冻结更新自身,直到控制器完成。否则,该表试图表示一个不断变化的数据列表。

        6
  •  0
  •   ferdil    14 年前

    你解决这个问题了吗?

    a) 不使用缓存-即最初创建FRC时调用不使用缓存:

     NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]
    

    (见cacheN)ame:nil)