您的位置:首页 > 移动开发 > Objective-C

iOS objective-C retainCount, OC计数器的思考

2013-03-24 18:19 357 查看

iOS objective-C retainCount, OC计数器的思考

学OC,肯定知道内存管理机制的原则。这里说说某些特殊的情况。

之前曾说,NSString的计数器比较特殊,大家注意下。

今天说另外一种,也是比较纠结的,以至于朋友都说这是OC BUG。。。

创建一个Class:



//H
#import <Foundation/Foundation.h>

@interface Car : NSObject

- (void)show;

@end

//M
#import "Car.h"

@implementation Car

- (void)show;{
NSLog(@"exec Finished!!!");
}

@end




很简单的show方法,确认Car类是否被free;

运行方法:

Car *car = [[Car alloc] init];
[car show];
[car release];
[car show];
NSLog(@"car retainCount:%d", [car retainCount]);


某些人可能一眼看出,执行未完成就会Crash;

但事实是,毫无Crash征兆,并且retainCount printf 1;

为什么会这样??经过与几个基友讨论,得出以下结论:

1.car堆被标记,即release执行完成,但因为不是立即释放,所以内存还存在;

2.存在栈中的car指针不由我们控制,同样未释放。

所以,给car指针指向的那块内存发送show消息时,又得到了结果。

既然不是OC的BUG,那如果避免?

在我们的项目中,肯定不会出现这样的问题,因为当堆被标记,有新创建的OBJ,会自动占用掉。

可以这样模拟:



Car *car = [[Car alloc] init];
[car show];
[car release];
for (int i = 0; i < 1000; i++) {
@autoreleasepool {
NSString *str = [NSString stringWithFormat:@"X%d", i];
NSLog(@"%@", str);
}
}
[car show];
NSLog(@"%d", [car retainCount]);




此时,不等运行到显示car的retainCount,已经Crash;

符合我们的结论;

如何避免就是大家熟悉的,在release后再设置nil即可;

其他的内存方面就不说了,只说奇葩的部分!!不对的地方请指出,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: