美文网首页iOS Developer
从Objective-C copy strong 说开去

从Objective-C copy strong 说开去

作者: 1a392df793c3 | 来源:发表于2017-07-13 17:58 被阅读61次

    为什么NS* 要使用copy修饰?
    为什么NSMutable*要用strong修饰?

    First, 我们得看下copy和strong有什么区别,它们都是属性的修饰符,关键在于它们对应了不同的setter方法实现

    strong :
    -(T)setA:(T)a {
        if (_a != nil) {
            [_a release];
        }
        [a retain];
        _a = a;
        return _a;
    }
    
    copy:
    -(T)setA:(T)a {
        if (_a != nil) {
            [_a release];
        }
        _a = [a copy]; // 如果a是可变类型,则返回一个不可变副本,
                       // 如果a是不可变类型,则返回其本身
        return _a;
    }
    
    这里插播一段小知识:下划线使用属性和self.使用属性有啥区别

    使用下划线对属性赋值时,是直接对属性赋值,如

    @property (nonatomic, strong) T *a;
    T *b = [[T alloc] init];
    _a = b; 
    

    这里 b 的引用计数不会加一,_a 直接指向了b指向的地址,引用计数仍为一,如果使用MRC的情况下,

    [b release]; 
    

    这时再进行

    [_a release]; 
    

    则会崩溃,原因就在于引用计数原先没有增加,

    [b release];
    

    后引用计数已经为0了。当引用计数为0时,系统就会调用delloc释放该对象和该对象所拥有的实例,该对象就销毁了。
    而使用self.对属性赋值时则不同,它实际是调用了属性的setter方法

    欢迎回来,strong修饰的属性赋值时指向的是同一块地址,引用计数加一,属于浅拷贝,而使用copy修饰的属性在赋值时将获得右值的一份不可变的副本

    For example,如果使用strong修饰一个NSString *属性aStr

    @property (nonatomic, strong) NSString *aStr;
    NSMutableString *mStr = [[NSMutableString alloc] init];
    self.aStr = mStr;     //这里mStr引用计数为2
    _aStr = mStr;         //这里mStr引用计数仍为2
    

    使用NSString *是说明定义的属性在初始化后其内容不应该再改变了,NSMutableString *是说明定义的属性内容可以改变,而这时如果将mStr赋值给aStr,因为使用的是strong修饰符,那么aStr将指向mStr的地址,mStr改变值的时候aStr的值也改变了,将与原意相悖;而使用copy修饰就不会有这情况产生了。

    而如果将一个可变属性用copy修饰,则可能会造成灾难性结果(请先再回看下上文中copy对应的setter方法):

    @property (nonamatic, copy) NSMutableString *mStr;
    _mStr = [[NSMutableString alloc] init];
    

    这里是直接赋值,mStr还是得到一个可变类型的结果,但是

    self.mStr = [[NSMutableString alloc] init];
    

    如果使用了self. 那么将会调用setter方法,则mStr将会得到一个不可变类型的结果 __NSCFConstantString,按照原意mStr是可以改变的,而这里mStr的类型已经变为不可变类型了,此时再对其进行append等操作,则会crash

    这就是为什么NS* 使用copy修饰,而NSMutable*则使用strong修饰的原因了

    那么这里为什么类型会变呢,明明声明定义的是NSMutableString类型的属性,为什么结果得到的却不是呢,这里就需要了解另外一个概念--类簇

                                                         -- Thusday, 13 July 2017

    相关文章

      网友评论

        本文标题:从Objective-C copy strong 说开去

        本文链接:https://www.haomeiwen.com/subject/uuqghxtx.html