assign 基本数据类型(char,short,int,float,double)
retain 对象类型
copy 对象类型,且遵守了<NSCopying>协议
assign下的属性内部实现:直接赋值的方法
@property (nonatomic, assign)NSString *name;
setter 方法
- (void)setName:(NSString *)name {
_name = name;
}
getter 方法
- (NSString *)name {
return _name;
}
main.m代码
NSString *name = [NSString alloc] initWithFormat:@“张三”];
Person *p = [[Person alloc] init];
p.name = name;
[name release];
NSLog(@“%@”,
p.name);
[p release];
该方法容易出现野指针异常,name已经被释放,在去访问p.name就会出现野指针。
retain下的属性内部实现:间接赋值
@property (nonatomic, retain) NSString *name;
setter方法
-(void)setName:(NSString *)name {
第一次时,_name是空指针,执行release没有任何变化,第二次_name有值,将第一次的_name释放。
if(_name != name) {
[_name release];
_name = [name retain];
}
}
getter方法
- (NSString *)name {
getter方法是安全的,使用getter方法不会改变原来实例变量的引用计数
return [[_name retain] autorelease];
}
copy方法与retain方法一样,间接赋值。
代码的演示:
@property (nonatomic, copy)NSString *name;
@property (nonatomic, copy)NSString *gender;
Person *p = [[Person alloc]initWithName:@"zhangsan” gender:@"m"];
执行初始化中的setter方法,将常量区的zhangsan拷贝到堆区,定义一个指针p指向堆区首地址。
p.name = @“lisi”;
p.gender = @"f";
name属性定义copy,copy首先释放了堆区中的_name实例变量(zhangsan副本被释放),赋值lisi,执行一次setter方法,指针指向从常量区拷贝到堆区的lisi的首地址。
NSLog(@"person‘s name is %@, gender is %@",p.name, p.gender);
[p release];
释放p,最后留下了lisi实例变量,造成内存泄漏。
dealloc是NSObject的一个实例方法,用于回收alloc开辟的内存空间。
在引用计数为0时,由系统自动调用。
copy、retain等修饰的属性的实例变量的内存泄漏问题(setter方法),可以在dealloc中释放类的实例变量。
重写dealloc方法:

便利构造器的内存管理,加上autorelease

在MRC中,对象如果是遍历构造器创建的,不要释放此对象,因为在创建遍历构造器时已经做了autorelease去释放。
集合的内存管理
集合在作为类的对象初始化时:
@property (nonatomic, retain)NSMutableArray *mArr;
_mArr = [[[NSMutableArray alloc]initWithCapacity:0] autorelease];
_mArr是getter方法,只有alloc,引用计数为1,在后面加autorelease或者重写dealloc方法中释放[_mArr release]
self.mArr = [[[NSMutableArray alloc]initWithCapacity:0] autorelease];
self.mArr是getter方法,alloc引用计数从0到1,之后,setter方法引用计数加1,在后面加上autorelease,还要在dealloc方法中加[_mArr release],释放两次。
加入容器的对象会被执行一次retain操作,引用计数加1
移除容器的对象会被执行一次release操作,引用计数减1
当容器自身释放时,会向容器中的所有储存的对象发送一次release消息
KVC(Key-Value-Coding),键值编码,是一种间接访问实例变量的方法,Key:键,用与标识实例变量,Value:实例变量对应的值
KVC在没有get/set方法,同样可以读写。
第一种
设置值:setValue:forKey:
取值:valueForKey:
第二种
设置值:setValue:forKeyPath:
取值:valueForKeyPath:
通过路径为实例变量赋值和取值
第三种:
setValuesForKeysWithDictionary:
字典中取值和赋值时,避免赋值匹配出现的崩溃问题,可以重写以下两种方法:

KVC实现机制:
1、检查是否在setter和getter方法中有实例变量的方法。
2、如果没有上述方法,检查是否存在实例变量的命名。