【问题标题】:How does the setter of a Core Date attribute manage memory?核心日期属性的设置器如何管理内存?
【发布时间】:2011-09-05 00:11:15
【问题描述】:

CoreData 属性的设置器是否保留?或复制值或设置器做什么?我想知道我是否必须(自动)释放我放入 setter 的值。

我已经对此进行了一些快速测试。假设以下模型:

+----------+
| Class A  |
+----------+
| v :int32 |
+----------+

然后生成的 ManagedObject 如下所示:

//A.h
@interface A :  NSManagedObject  
{
}
@property (nonatomic, retain) NSNumber * v;
//...

//A.m
@implementation A 
@dynamic v;
...

好的,该属性标记为retain,所以如果我将NSNumber 设置为v,则应该保留NSNumber。但它不是(我认为)。我做了以下事情:

A *a = ... ;
NSNumber *retainCheck = [[NSNumber alloc] initWithInt:23];
NSLog(@"retainCheck1: %i",[retainCheck retainCount]);
a.v = retainCheck;
NSLog(@"retainCheck2: %i",[retainCheck retainCount]);
NSLog(@"retainCheck3: %i",[a.v retainCount]);
NSLog(@"pointer1: %#x",retainCheck);
NSLog(@"pointer2: %#x",a.v);

这会产生以下输出:

retainCheck1: 1
retainCheck2: 1
retainCheck3: 1
pointer1: 0x62f068
pointer2: 0x62f068

两个 NSNumber 都是相同的 NSNumber 实例(相同的指针值 -> 所以它不会复制或类似的东西)并且 NSNumber 似乎没有被 setter 保留。

我在做某事吗?我的测试错了吗?还是 NSManagedObject-setter 的行为与标题中描述的不同?

编辑:我调用retainCount 是因为我想观察retain not release 或autorelease。观察到的行为可以用 Abizern 链接的享元模式来解释

【问题讨论】:

    标签: iphone objective-c core-data


    【解决方案1】:

    来自Core Data Programming Guide

    除了始终是非原子的之外,动态属性仅支持保留或复制属性——assign 被视为保留。您应该谨慎使用副本,因为它会增加开销。不能对关系使用复制,因为 NSManagedObject 不采用 NSCopying 协议,它与对多关系的行为无关。

    Core Data @dynamic 访问器始终保留分配时的属性。

    至于retainCount,不要那样看(正如@Abizern 和@Simon Goldeen 已经提到的那样)。 iOS 框架以自己的方式处理它,以确保内存管理规则成立。

    【讨论】:

      【解决方案2】:

      首先 - 不要担心 Core Data 如何管理它的属性 - 只要你释放你拥有的对象,这才是最重要的。

      其次 - 您正在使用 NSNumber 进行测试。 NSNumber 是一个奇怪的类,它采用了flyweight 设计模式,因此获取 NSNumber 的 retainCount 并不能告诉您任何有关 Core Data 如何管理其对象的信息。

      【讨论】:

      • 最后,不要调用retainCount。没用。
      • 哦,是的,我知道我忘了提到appropriate time 来使用retainCount。
      【解决方案3】:

      你不应该关心 Core Data 对象如何管理它的内存,只要相信它会正确地做到这一点。查看对象的保留计数很少有用,因为它可能会根据 Cocoa SDK 中的许多内容而改变。

      您需要做的就是确保每次在代码中调用allocretainnewcopy 时,它在某处与autoreleaserelease 保持平衡。

      【讨论】:

      • 所以我应该假设 setter 保留并且在这种情况下我应该释放我的 NSNumber?
      • 是的,因为你的代码中有[[NSNumber alloc] initWithInt:23];,在某些时候你应该释放那个对象。
      猜你喜欢
      • 1970-01-01
      • 2011-03-15
      • 1970-01-01
      • 2014-10-06
      • 2011-07-30
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      相关资源
      最近更新 更多