Cocos2d-x 的内存管理(6)
引用计数
简单情况
引用计数策略本身的思路很简单, 每有一个使用到内存块/资源的对象, 就对该内存块/资源的计数加一(retain), 每减少一个就减一(release), 当减到零的时候, 说明没有任何对象用到该内存块/资源, 就释放该内存块/资源.
在实际的使用过程中, 还是有些很dirty的事情, 那就是需要特别注意使用但是不想增加引用计数(assign/weak)的情况. 当两种情况混合的时候, 有的时候会很烦人, 特别的, 当引用计数使用的越多, 出现内存泄漏后, 要查明是哪儿不适当的retain, 或者哪儿有漏掉release就越难.
objc的简单情况下, 可以看成需要retain, release的配对.(类似new, delete的配对)
#import <Foundation/Foundation.h>
@interface Obj : NSObject {
}
- (id) init;
@end
@implementation Obj
- (id) init {
self = [super init];
if (self) {
NSLog(@"%d", __LINE__);
return self;
}
return nil;
}
- (void)dealloc {
NSLog(@"%d", __LINE__);
[super dealloc];
}
@end
void Test() {
id test = [[Obj alloc] init];
[test retain];
[test release];
[test release];
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
Test();
}
return 0;
}
上面的这种代码其实并没有什么意义, 因为情况太简单了, 需要记住alloc出来的对象引用计数为1即可, retain的调用也太明显了. 但是当有objc容器的时候, 就需要留心了.
容器对引用计数的影响
需要牢记的是objc的容器会隐式的retain对象, 并且接口都是类似AddXXX的形式. 此时光是去统计retain和release已经不管用了, 可以用所有权的思路去分析代码, 也就是把retain看成是宣示所有权, release看成是放弃所有权, 而容器一般都需要对对象拥有所有权.
以常见的NSArray容器为例, 在addObject后, 马上release, 可以看成是对象在当前作用域放弃所有权, 将其移交到容器中, 此时唯一拥有对象的就是容器, 当容器本身释放时, 该所有权也会跟着释放. 见下例:
#import <Foundation/Foundation.h>
@interface Obj : NSObject {
}
- (id) init;
@end
@implementation Obj
- (id) init {
self = [super init];
if (self) {
NSLog(@"%d: %s", __LINE__, __FUNCTION__);
return self;
}
return nil;
}
- (void)dealloc {
NSLog(@"%d: %s", __LINE__, __FUNCTION__);
[super dealloc];
}
@end
void Test() {
id test = [[Obj alloc] init]; // 1
NSLog(@"%d: %s, retain_count:%d", __LINE__, __FUNCTION__, [test retainCount]);
id array = [[NSMutableArray alloc] init];
[array addObject:test]; // 2
NSLog(@"%d: %s, retain_count:%d", __LINE__, __FUNCTION__, [test retainCount]);
[test release]; // 1
NSLog(@"%d: %s, retain_count:%d", __LINE__, __FUNCTION__, [test retainCount]);
[array release];
相关新闻>>
- 发表评论
-
- 最新评论 更多>>