coredata 学习总结(九)

Managed Objects and References

引用决定managed objects何时被释放和被retained。

Weak References Between Managed Objects and the Context

Managed objects知道和其联系的managed object context,managed object context也知道他自身拥有哪些managed objects。默认的,managed objects和context之间是weak引用。这意味着你不能依赖context来确定managed object实例的寿命。而且你也不能依赖现有的managed object来确定context的寿命。也就是说,你fetch了一个对象并不意味着他会一致存在。

managed object context有一个对任何有改变的对象的强引用(inserted, deleted, updated)直到做了save:之后。或者使用reset或者rollback给予忽略。

Creating a Strong Reference Between Managed Objects and the Context

可以通过设置retainsRegisteredObjects属性为true来改变context的默认行为。这样做的话就会使得managed objects依赖context的生命周期。如果在内存中缓存小数量数据,这样做很方便。例如,假设context控制了一系列的临时对象,比如是os x应用程序中的sheet或者ios程序中的modal view模态视图。如果你正操作多线程并且在不同的线程间传递数据,例如,如果你在后台进行fetch并且将object ids传递给主线程。后台线程需要在主线程上对这个对象的强引用直到他知道主线程使用了这些对象id给了错误的本地实例。否则对象可能不再存在于内存中并且需要从硬盘中再次得到。

使用独立的容器来持有那些你需要的managed objects。你可以使用array或者dictionary或者对象controller,(例如NSArrayController 实例)来对管理的对象采取强引用。你不需要的managed 对象当可能的时候会被dealloc掉。例如当关系被清除的时候。

If you have finished with a managed object context, or for some other reason you want to disconnect a context from its persistent store coordinator, donot set the context’s coordinator tonil.

当你结束了一个managed object context饰,或者由于其它一些原因将这个context从持久化协调器解除连接时,不要设置context的coordinator为nil。而应该放弃对context的拥有权并允许他被dealloc掉。

  1. [self setMyManagedObjectContext:nil];
  1. myManagedObjectContext = nil

Breaking Strong References Between Objects

managed objects中间的关系,每一个object都保留一个对于object或者objects的强引用。这种关系可以导致强引用循环。为了确保引用循环不发生,当完成对于一个对象的使用后,你可以使用managed object context 方法refreshObject:mergeChanges:来将managed object重置为默认的。

通常使用refreshObject:mergeChanges:来更新一个managed object的属性值。如果mergeChanges为yes,方法会将对象的属性值和在coordinator中存储的对象变量值merge到一起。如果为no,这个方法就不会将对象值做merge。这样就解除了强引用。
在一个managed 对象析构前,任何的强引用都必须被移出。包括core data外部的数据。

Strong References in Change and Undo Management

context保有对有未完成操作的managed objects(包括插入,删除,或者更新)的强引用,直到context发送了save:, reset:, rollback或者dealloc调用。或者context发送合适数量的undos来undo这些变化。如果对于undo的调用导致了特定对象的人和的改变,对象的强引用会变为weak引用。
和context相关的undo manager 会对任何有变化的managed objects保持强引用。默认的,context的undo manager持有无限制的undo和redo栈。为了限制应用程序的内存,需要保证使用removeAllActions

Ensuring Data Is Up to Date

确保数据是最新的。如果两个应用程序正在使用同样的数据存储,或者一个应用程序有多个持久化栈。很有可能一个managed object context中的managed 对象或者持久化存储对象和仓库中的contents不同步了。如果发生了这种情况,你需要在managed objects里更新数据,特别是持久化对象存储中来确保数据是最新的。

Refreshing an Object

managed 对象的属性值从持久化存储中产生。包括更新,插入,或者删除对象都需要开发人员来fetch请求。例如,假设某种场景,你请求一些对象并且在一个可编辑的context中修改它们,同时,在另外一个可编辑的context中你修改了同样的数据并且提交了修改。如果你在第一步的编辑后执行fetch请求来返回这个对象,你没有得到最近提交的数据。

可以使用managed object context方法refreshObject:mergeChanges:.来刷新一个managed 对象属性值。如果mergeChanges是yes,这个方法就会将在coordinator中的对象变量和其属性值merge到一起。如果这个flag是no,那么这个方法就会简单返回一个对象而不会merge。因此你可以使用这个方法来处理内存中的对象。

一个对象的过期间隔时间是直到存储重新提取快照。这个过期间隔只和incremental存储(例如 sqlite)相关。其它的存储不会重新提取,因为整个数据设置在内存中。

Merging Changes with Transient Properties

临时属性不在磁盘上存储。如果使用refreshObject:mergeChanges:设置yes属性,那么在调用awakeFromFetch后任何的临时属性会恢复到她们的预刷新值。这意味着,如果你有一个临时的变量需要依赖一个刷新了的属性,那么这个临时值有可能就无法同步。

假设有一个person实体并且有属性firstName和lastName,而且一个已经存储的临时属性fullname。假设fullname已经计算好了并且在自定义的acached方法中缓存了。

一个员工,名为"Sarit Smith"在持久化存储中。在两个managed object contexts中被编辑了:

  • 在context1中,对应的firstname变为Fiona。导致缓存的fullName更改为乐Fiona Smith,并且context被保存了。

    在持久化存储中,员工现在名为Fiona Smith

  • 在context2中,对应的lastname变为了Jones,导致缓存的fullname变为了Sarit Jones

            然后mergeChanges设置为yes来刷新这个object。更新从存储中抓取了Fiona Smith。对象更新如下:

    • 更新使得firstname值从持久化存储中读取,即Fiona
    • lastname对refresh发起响应,更新后,变回为之前修改的值Jones
    • 而临时的值,fullname,也对更新发起响应,更新后,fullname就重新存储为"Sarit Jones"。但是,正确结果应该是"Fiona Jones".

这个例子说明了,因为预更新的值都在awakeFromFetch,调用后采用,你就不能使用awakeFromFetch来保证临时的值会跟着更新来同步。所以最好的方案就是使用额外的实例变量来标注更新发生了,然后临时值需要重新计算。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值