属性的内部实现原理:
retain:
- (void)setTea:(Teacher *)tea{
//判断原有对象和新对象是否是同一个 如果是同一个,就没有必要再重新赋值了.否则会先release,release之后空间回收,此时再retain就变成野指针了
if (_tea != tea) {
[_tearelease];//释放之前对象保有的所有权,如果不释放,将会造成内存泄漏
// self.tea = tea; 相当于[self setTea:tea] 死循环
_tea = [tea retain]; //让实例变量_tea保有新的对象的所有权.
}
}
- (void)setTea1:(Teacher *)tea1{
if (_tea1 != tea1) {
[_tea1 release];
//如果想对一个对象进行copy操作,对象的类必须服从NSCopying协议,并实现协议中的方法
_tea1 = [tea1 copy];
}
copy协议中的方法:
- (id)copyWithZone:(NSZone *)zone{
Teacher *newTea = [[Teacher allocWithZone:zone] init];
newTea.name = self.name;
newTea.gender = self.gender;
return newTea;
}
+ (id)teacherWithName:(NSString *)name gender:(NSString *)gender{
Teacher *teacher = [[Teacher alloc] initWithName:name gender:gender];
return [teacher autorelease];
}
遵循内存管理的黄金法则,外部在使用便利构造器的时候,不用手动release
colletion(集合)的内存管理:
当把一个对象放入集合中时(数组,字典,集合),会将对象的引用计数+1,因为内部做了retain操作.
当集合(数组,字典,集合等),空间被回收时,他们会向空间中的每一个元素发送一个release消息(对应添加元素时 的retain操作)
从数组中移除一个元素时,会release高对象,引用计数-1
当对象的属性特性为retain是,在对象用完被回收时,需要对象的实例变量进行引用计数清0操作,即重写dealloc方法:
- (void)dealloc
{
NSLog(@"%@空间已回收", self.name);
[_name release];
[_gender release];
[super dealloc];
} (代码中的name,gender属性语义特性声明为retain)