Objective-C的retainCount的基本用法

时间:2014-01-11 14:07:18

标签: objective-c retaincount

我们都知道retain方法将+1 retainCount,释放将保留-1 retainCount,如果retainCount == 0,则对象dealloc。 但我遇到了一个问题,下面的代码运行得到了荒谬的结果

#import <Foundation/Foundation.h>
@interface Person : NSObject
@property(nonatomic, retain) NSString *name;
@property(nonatomic, assign) NSInteger age;

@end

@implementation Person
- (id)init
{
    self = [super init];
    if (self) {
        self.name = @"name";
        self.age = 20;
    }
    return self;
}

- (void)dealloc
{
    NSLog(@"dealloc");
    [super dealloc];
}
@end

int main(int argc, const char * argv[])
{
    Person *per1 = [[Person alloc] init];
    NSLog(@"retainCount = %lu -- 1",[per1 retainCount]);
    [per1 release];
    [per1 retain];
    NSLog(@"retainCount = %lu -- 2",[per1 retainCount]);
    return 0;
}

结果是:

2014-01-11 21:56:23.887 blockTest[1287:303] retainCount = 1 -- 1
2014-01-11 21:56:23.889 blockTest[1287:303] dealloc
2014-01-11 21:56:23.889 blockTest[1287:303] retainCount = 2 -- 2

我不使用ARC。为什么我得到这个结果? 应用程序不应该崩溃吗?

3 个答案:

答案 0 :(得分:7)

这里发生的事情是,尽管该对象已被解除分配,但它所存储的内存尚未被覆盖,因此后来的调用仍然有效,因为数据暂时仍在那里。

最后得到retainCount为2的原因是当您将release发送给retainCount为1的对象时,他们只需dealloc该对象直接离开,没有费心将内部计数减少到零。

答案 1 :(得分:3)

你不应该期望这个属性会返回任何有意义的结果 你做什么并不重要,这不是你的工作。

有关详细信息whentouseretaincount.com

,请参阅此处

答案 2 :(得分:2)

取消分配对象后,您无法向该对象发送任何进一步的消息。在您的情况下,一旦您向其发送release消息,就会释放您的对象。发送任何其他消息(包括retainretainCount)是未定义的行为。

例如,在我的系统上,代码如下:

int main(int argc, const char * argv[])
{
    Person *per1 = [[Person alloc] init];
    [per1 release];
    Person *per2 = [[Person alloc] init];
    per2.name = @"Something Else";
    [per1 retain];
    NSLog(@"per1.name = %@",per1.name);
    return 0;
}

打印:

per1.name = Something Else

更多未定义的行为!