Iphone发布问题

时间:2011-01-11 22:14:05

标签: iphone memory-management

我在.h

中有以下代码
@property (nonatomic, copy) NSString *username;

然后,当用户在TextField中输入文本时,以这种方式分配用户名:

self.username = textField.text;

然后,在dealloc方法中我调用release:

NSLog(@"%d",[username retainCount]);
[username release];
NSLog(@"%d",[username retainCount]);

但是在控制台中它会打印出来:

2011-01-11 23:09:52.468 IApp [2527:307] 1
2011-01-11 23:09:52.480 IApp [2527:307] 1

有什么问题?

由于

4 个答案:

答案 0 :(得分:6)

发布后,对象被销毁,因此第二次调用'retaincount'有未定义的行为

答案 1 :(得分:4)

  

有什么问题?

问题在于您正在使用retainCount并希望获得有意义的结果。

不要调用retainCount

When to use -retainCount?

以上有一些很好的细节。这里的答案之一也是如此:

https://stackoverflow.com/questions/4580684/common-programming-mistakes-for-objective-c-developers-to-avoid


请注意,您可以设置MallocScribble环境变量,这将导致分配的内存在分配时填充0xaa字节,在释放时填充0x55字节。面对这种情况,您对retainCount的第二次调用将会崩溃。

答案 2 :(得分:3)

第一次释放时,保留计数为1.由于内存即将被释放,因此没有“需要”减少保留计数,因此底层代码可能只是跳过减量步骤并取消分配记忆。

当您第二次查看保留计数时,您正在查看解除分配的内存,这是不安全的,并且可能会返回任何值。自从它立即之后 release,内存可能尚未分配给其他内容,但无论如何都不应该访问它。

答案 3 :(得分:3)

不会立即释放对象。 可能在对象真正释放之前必须有一个运行循环周期 但是调用retainCount真是件有意义的事情。请阅读原因:When to use -retainCount?

编辑:@ kris-van-bael评论了这个答案 - 正确 - 基于文档,这不是真的。所以我必须清楚地说明我在这里写的是基于在iOS模拟器上测试这个问题 - 而不是它应该事情的工作方式。但是,似乎以下代码将运行而没有错误:

@interface Test : NSObject { }
@property (retain, nonatomic) NSString *test;
@end

@implementation Test
@synthesize test;
@end

然后在代码中的某处写:

Test* t = [[Test alloc] init];
t.test = @"Test1";

NSLog(@"%@", t.test);

[t release];

t.test = @"Test2";

NSLog(@"%@", t.test);    

这个(不幸的)将在iOS模拟器上运行时没有错误(但是在调试器崩溃的情况下逐步执行它),所以在iOS中解除分配对象显然有一些技巧。