OC内存管理黄金法则(译文):如果一个对象使用了alloc,[mutable]copy,retain,那么你必须使用相应的release或者autorelease释放。
Xcode建立Command Line Tool项目:DogSample,选择手动管理内存,并添加Dog和Person类。
Dog有唯一标识的ID属性,Dog.h代码:
#import
{int _ID;
}@property int ID;@end
添加对象retainCount=0时自动调用的dealloc 函数,Dog.m代码:
#import "Dog.h"@implementation Dog@synthesize ID = _ID;- (void) dealloc
{NSLog(@"Dog %d is dealloc ...", _ID);[super dealloc];
}@end
Person对象有Dog属性,表示某某人拥有某某狗,Person.h
#import
#import "Dog.h"@interface Person : NSObject
{Dog *_dog;
}- (void) setDog:(Dog *)newDog;
- (Dog *) dog;@end
同样,Person.m代码如下:
#import "Person.h"
#import "Dog.h"@implementation Person- (void) setDog:(Dog *)newDog;
{//暂时不写
}- (Dog *) dog
{return _dog;
}- (void) dealloc
{NSLog(@"Person is dealloc ...");[super dealloc];
}@end
下面我们来看main.m的实现,首先创建一条狗狗和人类小丽,我们用 [xiaoLi setDog:dog1]; 表示小丽拥有dog1
#import
#import "Dog.h"
#import "Person.h"int main(int argc, const char * argv[])
{@autoreleasepool {//NSLog(@"Hello, World!");
Dog *dog1 = [[Dog alloc] init];[dog1 setID:1];Person *xiaoLi = [[Person alloc] init];//小丽拥有狗狗 dog1
[xiaoLi setDog:dog1];}return 0;
}
那么Person.m的setDog函数具体该如何实现呢?画图分析:
1.我们需要把 dog1赋值给xiaoLi对象的_dog属性,让小丽拥有dog1
2.所以dog1指向的对象其现在应该是reatainCount=2了,所以setDog函数添加如下代码:
if(newDog != _dog){_dog = [newDog retain];
}
现在假设我们release人类xiaoLi,那么Dog的retainCount=1还是retainCount=2 ??我们写一下代码测试:
[xiaoLi release];NSLog(@"xiaoli release, dog1 retainCount is %lu", [dog1 retainCount]);
运行结果:
Person is dealloc ...
xiaoLi release, Dog retainCount is 2
引用计数器仍然是2,说明当我们释放xiaoLi的时候,并没有因为_dog属性指向Dog对象的关系而自动执行 [dog1 retain],而是需要我们手动去实现:
- (void) dealloc
{NSLog(@"Person is dealloc ...");//添加代码:需要手动使Dog的retainCount减1
[_dog release];[super dealloc];
}
这时候的内存示意图如下:
点击这里下载源代码