属性关键字

readonly和readwrite

这2个简单,一个只读的,一个可读可写的。一般在使用readonly的地方,防止KVC修改值,都会加上+ (BOOL)accessInstanceVariablesDirectly,返回NO;

atomic和nonatomic

atomic原子的,系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。但是对其修饰的比如数组添加删除成员变量,是线程不安全的。
nonatomic是线程不安全的,nonatomic的速度要比atomic的快。
atomic与nonatomic的本质区别其实也就是在setter方法上的操作不同

nonatomic对象setter和getter方法的实现:
- (void)setCurrentImage:(UIImage *)currentImage
{
    if (_currentImage != currentImage) {
        [_currentImage release];
        _currentImage = [currentImage retain];
    }
}
- (UIImage *)currentImage
{
    return _currentImage;
}
atomic对象setter和getter方法的实现:
- (void)setCurrentImage:(UIImage *)currentImage
{
    @synchronized(self) {
        if (_currentImage != currentImage) {
            [_currentImage release];
            _currentImage = [currentImage retain];
        }
    }
}
- (UIImage *)currentImage
{
    @synchronized(self) {
        return _currentImage;
    }
}

assign

修饰基本数据类型,int、bool
修饰对象类型时,不改其变引用计数
会产生悬垂指针

weak

不改变被修饰对象的引用计数
所指向的对象在被释放之后会自动置为nil

__unsafe_unretained

修饰对象类型,不改其变引用计数
会产生悬垂指针

strong

修饰对象类型,产生抢引用,引用计数加1

copy深拷贝浅拷贝

浅拷贝:对内存地址的复制,目标对象和原对象指向同一个内存地址,引用计数加1
深拷贝:目标对象和原对象指向两个内容相同的内存空间,不影响引用计数

image.png

可变对象的copy和mutableCopy都是深拷贝
不可变对象的copy是浅拷贝,可变对象的copy是深拷贝
copy返回的都是不可变对象

MRC下如何重写retain变量的setter方法?

- (void)setObj:(id)obj
{
      if (_obj != obj) {
          [_obj release];
          _obj = [obj retain];
      }
}
_obj != obj 这个判断是防止这2个是同一个对象时,下面[_obj release]会把这个对象释放掉,外面再调用时会崩溃。

你可能感兴趣的:(属性关键字)