转:http://tigercat1977.blog.163.com/blog/static/2141561122012111293721234/
第四讲:Obj-C 内存管理2 - retain / copy
retain 属性主要作用
@property (retain) 编译器如何申明
@synthesize 编译器如何展开实现
dealloc 需要注意内容
copy 属性的主要内容
OC 内存管理和点语法
OC 内存管理正常情况要使用大量的 retain 和 release 操作
点语法可以减少使用 retain 和 release 的操作
Person.h 头文件申明
@interface person: NSObject
{
Dog * _dog;
}
@property (retain) Dog *dog;
@end
Person.m 实现文件
@implementation Person
@synthesize dog = _dog
- (void) dealloc
{
self.dog = nil;
[super dealloc];
}
编译器对于 retain 展开形式
编译器对于 @prooerty 中的 retain 展开是不一样的
主要是要释放上一次的值,增加本次计数器
@property 展开(retain 属性)
@property(retain) Dog *dog;
仍然是展开为:
- (void) setDog:(Dog *)aDog;
- (Dog*) dog;
@synthesize ( retain 属性)
@synthesize dog = _dog;
展开为:
- (void) setDog:(Dog*) aDog{
if (_dog != aDog) {
[_dog release];
_dog = [aDag retain];
}
}
- (Dog*) dog {
return _dog;
}
dealloc 必须要释放 dog (retain)
- (void) delloc
{
self.dog = nil;
[super dealloc];
}
copy属性
copy 属性是完全把对象重新拷贝了一份,计数器从新设置为1, 和之前拷贝的数据完全脱离关系
@property (copy) NSString* str;
// 表示属性的 getter 函数
- (double) str
{
return str;
}
// 表示属性的 setter 函数
- (void) setStr:(NSString*) newStr
{
str = [newStr copy];
}
assign , retain , copy
foo = value;
// 简单的引用赋值
foo = [value retain];
// 引用赋值,并且增加 value 的计数器
foo = [value copy];
// 将 value 复制了一份给 foo, 复制后, foo 和 value 就毫无关系
举例 (把上一讲的改一下,运行结果不变)
// Dog.h #import <Foundation/Foundation.h> @interface Dog : NSObject { int _ID; } @property int ID; @end
// Dog.m #import "Dog.h" @implementation Dog @synthesize ID = _ID; - (void) dealloc { NSLog(@"dog %d is dealloc", _ID); [super dealloc]; } @end
// Person.h #import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject { Dog *_dog; } @property (retain) Dog *dog; /* 被上一行代替 - (void) setDog:(Dog *)aDog; - (Dog *) dog; */ @end
// Person.m #import "Person.h" @implementation Person @synthesize dog = _dog; /* 被上一行代替 - (void) setDog:(Dog *)aDog { if (aDog != _dog) { [_dog release]; _dog = [aDog retain]; // 让计数器 +1 } } - (Dog *) dog { return _dog; } */ - (void) dealloc { NSLog(@"person is delloc"); // 把人拥有的 _dog 释放 // [_dog release] 等于 _dog = nil self.dog = nil; // [self setDog:nil]; 和上边一行相等 [super dealloc]; } @end
// main.m #import <Foundation/Foundation.h> #import "Dog.h" #import "Person.h" int main (int argc, const char * argv[]) { @autoreleasepool { Dog *dog1 = [[Dog alloc] init]; [dog1 setID:1]; Dog *dog2 = [[Dog alloc] init]; [dog2 setID:2]; Person *xiaoLi = [[Person alloc] init]; // 小丽要遛狗 [xiaoLi setDog:dog1]; [xiaoLi setDog:dog2]; NSLog(@"dog1 retain count is %ld", [dog1 retainCount]); //输出:dog1 retain count is 1 [dog1 release]; //输出:dog 1 is dealloc NSLog(@"dog2 retain count is %ld", [dog2 retainCount]); //输出:dog2 retain count is 2 [xiaoLi release]; //输出:person is delloc NSLog(@"dog2 retain count is %ld", [dog2 retainCount]); //输出:dog2 retain count is 1 [dog2 release]; //输出:dog 2 is dealloc } return 0; }
(这讲完)