保留合成属性的计数

时间:2011-04-25 16:34:45

标签: objective-c properties retaincount

请查看我的代码:

@interface ClassA : NSObject {
    ClassB *objB;
}

@property (retain) ClassB *objB;
@end

@implementation ClassA:
@synthesiaze objB;
@end

int Main(int argc, const char *argv[])
{
    ClassA *objA = [[ClassA alloc] init];
    ClassB *objB = [[ClassB alloc] init];

    NSLog(@"%d", (int)[objB retainCount]);    // 1
    NSLog(@"%d", (int)[[objA objB] retainCount]);     // 0

    objA.objB = objB;

    NSLog(@"%d", (int)[objB retainCount]);    // 2
/* --> */    NSLog(@"%d", (int)[[objA objB] retainCount]);     // 3
    NSLog(@"%d", (int)[[objA objB] retainCount]);     // 4
    NSLog(@"%d", (int)[objB retainCount]);    // 4
}

请查看第23行NSLog(@"%d", (int)[[objA objB] retainCount]);

我认为结果应该是2而不是3,但每次调用[objA objB]似乎都会将保留计数增加1.我不知道发生了什么。谁能告诉我?谢谢!

3 个答案:

答案 0 :(得分:4)

Apple有关于retainCount的说法:

  

重要说明:此方法在调试内存管理问题时通常没有价值。因为任何数量的框架对象可能保留了一个对象以保存对它的引用,而同时自动释放池可能在对象上保留任意数量的延迟版本,所以您不太可能从此获取有用信息方法。

     

要了解您必须遵守的内存管理的基本规则,请阅读“Memory Management Rules”

不要担心保留计数;如果您致电releaseretain或名称以alloccopymutableCopy开头的方法,请致电new

答案 1 :(得分:3)

首先,不要依赖retainCount始终保持100%准确。

那就是说,你所看到的只是因为合成的吸气剂看起来像这样:

- (ClassB *)objB
{
    return [[objB retain] autorelease];
}

因此,当您通过合成的getter请求对象时,它会被保留并自动释放。这是因为你从非所有权获取者获得的任何东西都应该持续当前自动释放池的生命周期,但如果你在过渡期间释放了objA,那么情况就不会如此。

答案 2 :(得分:2)

您的@property未标记为非原子,因此getter不仅仅是一个简单的返回,而是一个锁定,保留,自动释放和解锁 - 用于线程安全目的。您可以编写自己的getter或将属性声明为@property(nonatomic,retain)