我们都知道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。为什么我得到这个结果? 应用程序不应该崩溃吗?
答案 0 :(得分:7)
这里发生的事情是,尽管该对象已被解除分配,但它所存储的内存尚未被覆盖,因此后来的调用仍然有效,因为数据暂时仍在那里。
最后得到retainCount
为2的原因是当您将release
发送给retainCount
为1的对象时,他们只需dealloc
该对象直接离开,没有费心将内部计数减少到零。
答案 1 :(得分:3)
你不应该期望这个属性会返回任何有意义的结果 你做什么并不重要,这不是你的工作。
有关详细信息whentouseretaincount.com
,请参阅此处答案 2 :(得分:2)
取消分配对象后,您无法向该对象发送任何进一步的消息。在您的情况下,一旦您向其发送release
消息,就会释放您的对象。发送任何其他消息(包括retain
和retainCount
)是未定义的行为。
例如,在我的系统上,代码如下:
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
更多未定义的行为!