美文网首页
1.2 property 关键字 —— copy

1.2 property 关键字 —— copy

作者: 哈库呐玛塔塔__ | 来源:发表于2020-05-13 02:13 被阅读0次

    1.什么时候使用copy。

    copy修饰的是不可变的对象。即使后边声明的是NSMutableXXX ,它实际上的真实数据类型也是不可变的。这时候对其进行操作就会崩溃了。

    copy用作浅拷贝,只拷贝对象的指针,对象的内存是不变的。只是新开辟了一块指针类型的内存空间,这个内存空间里的内容是指向这个对象的指针。

    通常情况下,当我们定义属性的时候,我们想要的是一个不可变的对象的时候。比如NSString,NSArray。

    当我们给这个不可变的对象赋值的时候,要分两种情况考虑。

    @property (nonatomic, copy) NSString *copyedString;

    @property (nonatomic, strong) NSString * strongString;

    ①所赋的值对象也是不可变的。 

        NSString *string = @"123asd";

        self.copyedString = string;

        self.strongString = string;

        NSLog(@"stringP = %p ",string);

        NSLog(@"self.copyedStringP = %p  self.copyedString class = %@", self.copyedString, [self.copyedString class]);

        NSLog(@"self.strongStringP = %p  self.strongString class = %@", self.strongString, [self.strongString class]);

    运行结果:

     stringP = 0x10e4f9078

     self.copyedStringP = 0x10e4f9078  self.copyedString class = __NSCFConstantString

     self.strongStringP = 0x10e4f9078  self.strongString class = __NSCFConstantString

        ②所赋的值对象是可变的。

        NSString *string = @"123asd".mutableCopy;

        self.copyedString = string;

        self.strongString = string;

        NSLog(@"stringP = %p ",string);

        NSLog(@"self.copyedStringP = %p  self.copyedString class = %@", self.copyedString, [self.copyedString class]);

        NSLog(@"self.strongStringP = %p  self.strongString class = %@", self.strongString, [self.strongString class]);

    运行结果:

     stringP = 0x600001e9b4e0

     self.copyedStringP = 0xc862b1052a14edfe  self.copyedString class = NSTaggedPointerString

     self.strongStringP = 0x600001e9b4e0     self.strongString class = __NSCFString

    当是第一种情况的时候其实strong和copy是没有区别的,_str的指针地址都一样,二者都是对string的引用计数加了1.

    但是第二种情况的时候用strong修饰,和第一种情况仍然一样,引用计数加1,但此时虽然声明是NSString,但是strongString是对string这个可变字符串变量的一次持有,实际上strongString指向的就是这个可变的字符串,所以现在的strongString并不是不可变的字符串了。而copyedString不一样,copy时string的内存空间是可变的,与copyedString声明的所有权修饰符copy并不符合,所以此时需要做深拷贝,拷贝了内容,放在一块新的内存不可变的地址中去。

    2.一种错误的使用情况

    当 copy 修饰可变类型集合(例如:NSMutableArray)时,赋值后,会导致可变类型属性变为不可变类型,然后在调用可变类型方法时,会产生异常错误。

    产生异常的原因是 copy 属性在运行时赋值时调用了 -copyWithZone:赋值,将可变类型转换为不可变类型。

    3.一道题

    所以表面上self.array是NSArray对象, 其实骨子里是NSMutableArray对象.这样的话将会对后期DEBUG增加很大的成本, 可能会导致莫名其妙的错误.

    相关文章

      网友评论

          本文标题:1.2 property 关键字 —— copy

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