天天看点

OCMRR模式下重写属性变量的set方法和get方法

由于MRR模式下系统是不会自动释放掉我们不用的对象的,所以对于频繁使用的属性变量,我们就应该重写他们的set来避免重复赋值(但是不能同时重写set和get方法,否者系统就不会为我们创建 _属性变量名 的成员变量)。

 重写属性变量的set方法

有时候我们需要第一时间知道数据改变了,这个时候我们就需要重写set方法。
#import "Person.h"

@implementation Person

- (void)dealloc{
    [self.name release];
    [self.che release];
    
    [super dealloc];
}

- (void)setName:(NSString *)aName{
    //判断是否相同
    if (_name != aName){
        //1.释放掉之前
        [_name release];
        
        //2.赋值
        _name = [aName retain];
        /*这里不能用self. 所以我们用了成员变量,而self.可以帮助我们在设置name的值的同时根据属性
        关键字来设置name对aName所指的对象的拥有权。这里不能用self. 所以我们在aName后面加了一个 
        retain*/
                       
    }
}
@end
           

在.m的实现文件中,我们重写了set方法,首先避免重复赋值我们判断了当前的对象与我们传递的对象是否相同,如果不同,我们将之前的对象先释放掉,然后参数声明为retain在赋值给当前对象,加retain的原因是我们希望 _name 对这个传递的对象有它自己的拥有权,否则容易导致 访问已释放对象 的错误。注意这里最后一步是不能用 self.name 来设置的,因为那样就会导致递归调用,陷入死循环,同样的在get方法里面也不能让 self.name 处在赋值号右边,因为那样就会循环调用get方法,而陷入死循环。

 重写属性变量的get方法

第一时间知道需要访问这个数据了,或者有些数据或者事情只有当需要的时候才去创建或者加载的时候,我们需要重写get方法。这种机制叫做lazyload(懒加载)
#import "Person.h"

@implementation Person

- (void)dealloc{
    [self.name release];
    [self.che release];
    
    [super dealloc];
}

- (void)setName:(NSString *)aName{
    //判断是否相同
    if (_name != aName){
        //1.释放掉之前
        [_name release];
        
        //2.赋值
        _name = [aName retain];
    }
}

-(NSString *)name{
    //首先判断是否是第一次访问

    if(_name==nil){//这里不能用self.来访问,否则会造成死循环
      //说明是第一次访问,就做一些准备,比如说分配一些空间
      self.name = [NSString new];//这里调用self.调用的是set方法不会造成死循环
    }
    
    return _name;
}
@end
           

代码如上,name是get方法名。