【问题标题】:Retain count of a synthesized property保留合成属性的计数
【发布时间】:2011-04-25 16:34:45
【问题描述】:

请检查我的代码:

@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。我不知道发生了什么。谁能告诉我?谢谢!

【问题讨论】:

  • retainCount 如何无用地误导的真棒示例。 看起来保留计数增加了 1,但实际上是 retain/autorelease。因此,如果您在该示例中 [正确] 创建和排出自动释放池,则日志消息所暗示的保留将消失。 IE。 不要调用retainCount

标签: objective-c properties retaincount


【解决方案1】:

Apple 对retainCount 这么说:

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

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

不用担心保留计数;如果您调用retainalloc 或名称以copymutableCopynew 开头的方法,只需担心调用release

【讨论】:

    【解决方案2】:

    首先,不要依赖retainCount 总是100% 准确。

    也就是说,您所看到的只是因为合成的 getter 看起来像这样:

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

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

    【讨论】:

      【解决方案3】:

      你的@property 没有被标记为nonatomic,所以getter 不仅仅是一个简单的返回,而是一个锁、保留、自动释放和解锁——出于线程安全的目的。您可以编写自己的 getter 或将属性声明为 @property(非原子,保留)

      【讨论】:

        猜你喜欢
        • 2011-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-18
        • 2011-03-16
        • 2010-09-20
        • 1970-01-01
        相关资源
        最近更新 更多