我在使用Core Data和Magical Record工作了一段时间并且出错后,正处于开发iOS应用程序的过程中:
错误:NULL _cd_rawData但对象没有变成错误
我在这个项目之前并不知道Core Data,因为事实证明我非常天真地认为我可以使用Magical Record而不用担心并发性,因为我没有专注于管理上下文的任何想法/工作主线程和后台线程。
在大量关于核心数据管理对象上下文和魔法记录的阅读之后,我理解:
Entity *localEntity = [entity MR_inContext:localContext]
来处理后台线程上下文中的实体。saveWithBlock:completion:
和saveWithBlockAndWait:
方法来获取用于后台线程的托管上下文。关于我的申请的一些信息:
现在 - 我的问题是:
如果一切都清楚,请告诉我。如果没有,我会尝试增加清晰度。
任何帮助或指导都将不胜感激。
谢谢!
答案 0 :(得分:7)
我没有使用MagicalRecord,但这些问题与CoreData有关,而与MagicalRecord有关,所以我会尝试回答它们:)。
设计应用模型的方法有很多,所以我在几年内使用CoreData学到了两件重要的事情:
处理UI时,总是在主线程上获取对象。正如你所说的那样,NSManagedObjects 不是线程安全的,所以你不能(好吧,可以,但不应该)从不同的线程访问他们的数据。当您需要显示长列表时,NSFetchedResultsController是您最好的朋友(例如,对于消息 - 但请注意请求的批量大小)。
您应该设计存储和提取快速响应。使用索引,仅获取所需的属性,预取关系等。
如果需要从大量数据中获取,可以在不同的线程上使用上下文并仅传输NSManagedObjectID。让我们说你的用户有大量的消息,你想向他展示特定联系人的最新消息。您可以创建后台上下文(私有并发),获取这10个消息ID(NSManagedObjectIDResultType
),将它们存储在数组中(或任何其他合适的格式),将它们返回到主线程并仅获取这些ID。请注意,如果fetch需要很长时间,因为谓词/ sortDescriptor,如果"问题"正在将故障转化为对象(例如,存储在可转换属性中的大UIImage :))
您可以在后台上下文中创建对象,在保存上下文后存储它的NSManagedObjectID (对象在保存之前只有临时ID)并将其发送回主线程,在那里你可以通过ID执行获取并在主上下文中获取对象。
我不知道它是否是最好的,但我对NSManagedObjectContext观察和通知合并非常满意。查看: mergeChangesFromContextDidSaveNotification:
因此,您创建背景上下文,添加主上下文作为更改的观察者(NSManagedObjectContextObjectsDidChangeNotification
),后台上下文自动向您发送有关所有更改的通知(每次执行保存) - 插入/更新/删除的对象(不用担心,您可以通过调用mergeChangesFromContextDidSaveNotification:
来合并它)。这有许多优点,例如:
另一方面:
好吧,我希望它能回答你的问题。如果一切顺利,请不要犹豫,问:)
还要看看儿童情境。它们也很强大。基本上每个子上下文在保存时将其更改发送到父上下文(在" base" context(没有父上下文)的情况下,它将其发送给持久协调器)。
例如,当您创建编辑/添加控制器时,您可以从主上下文创建子上下文并执行其中的所有更改。当用户决定取消操作时,您只需销毁(删除引用)子上下文,不会存储任何更改。如果用户决定接受他/她所做的更改,请保存子上下文并销毁它。通过保存子上下文,所有更改都会传播到它的父存储(在此示例中为主上下文)。请务必同时保存父上下文(在某些时候)以保留这些更改(保存:方法不会执行冒泡)。结帐documentation of managing parent store。
快乐的编码!