retain和release配对使用;
只要出现retain、alloc、copy中的其中一个,就要用一次release;
只要retainCount为0,系统会自动调用dealloc
@property中使用的关键字
readwrite:属性会被当成读写的,默认 readonly:属性只可读不可写 assign:不会使引用计数加1,常用于数值 retain:会使引用计数加1,只在非ARC中使用 copy:建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝 nonatomic:非原子性访问,多线程并发访问会提高性能 atomic:原子性访问 strong:打开ARC时才会使用,相当于retain。 weak:打开ARC时才会使用,相当于assign,可以把对应的指针变量置为nil。
提示: NSArray *arr = [NSArray array]; 和 NSArray *arr = @[]; 等价,内部已经有了一个autorelease,不需要重复写release
根据谁使用谁撤销的原则,在dealloc方法中必须设置类类型的属性为空,即给类类型的属性来一次release
如下代码
A. 下面是不使用@property (nonatomic, retain) 的情况
---------- 关于Dog的类如上代码,这里只写Person类,下面是不使用@property (nonatomic, retain) 的情况 #import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject { Dog *_dog; } - (void)setDog:(Dog *)dog; - (Dog *)dog; @end @implementation Person - (void)dealloc { // 必须设置为nil,相当于对self.dog一次release // 保证Person对象不在的时候,dog的引用计数减一,因为是Person引用了一次 self.dog = nil; [super dealloc]; } - (void)setDog:(Dog *)dog { if (_dog != dog) { [_dog release]; _dog = [dog retain]; } } - (Dog *)dog { return _dog; } @end ---------- 关于使用Person类的内存管理 Person *person = [[[Person alloc] init] autorelease]; Dog *dog = [[[Dog alloc] init] autorelease]; person.dog = dog; person.dog = dog;// 即使有第二次赋值,引用计数器也不会加一 NSLog(@"person---%ld", person.retainCount); NSLog(@"person.dog----%ld", person.dog.retainCount);运行结果:
B. 下面是使用@property (nonatomic, retain) 的情况 这样的好处是不用手动去写类类型的属性的setter方法 上面的Person类可以改成
#import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject @property (nonatomic, retain) Dog *dog; @end @implementation Person - (void)dealloc { // 必须设置为nil,相当于对self.dog一次release // 保证Person对象不在的时候,dog的引用计数减一,因为是Person引用了一次 self.dog = nil; [super dealloc]; } @end修改后的运行结果一样:
copy属性是完全把对象重新拷贝了一份,计数器从新设置为1,和之前拷贝的数据完全脱离关系
和retain一样,如果不使用@property (nonatomic, copy) 就必须自己写下面的代码
@property (nonatomic, copy) NSString *string; - (NSString *) string { return _string; } - (void)setString:(NSString *)newStr { if (_string != newStr) { [_string release]; _string = [newStr copy]; }