美文网首页工作生活
iOS 有趣的属性修饰符和拷贝

iOS 有趣的属性修饰符和拷贝

作者: J扣歪 | 来源:发表于2019-07-01 14:22 被阅读0次

    一 @property

    @property 的作用是自动生成访问成员变量的接口setter getter 方法同时生成一个带"_"的实例变量

    二   atomic 和 nonatomic

    图片不是我的

    官方给出的解释 atomic是默认修饰符,它在setter getter方法内加了锁,可以防止我们在某一线程通过getter获取属性值的一刻恰好另个一条线程通过setter对该属性的值做出了改变而导致我们获取到的值不是我们想要的(由于程序运行速度极代码执行部分又过于简单快这种情况极少发生).而nonatomic则没有加锁.nonatomic相对于atomic性能要快一些所以我们经常使用nonatomic,而关于线程安全问题则根据开发需要在代码更外层加锁.

    三 @synthesize

    @synthesize的作用是为属性声明实例变量, 如图我将属性p的实例变量设置成了_p1, 如果调用原来的实例变量_p则会报错,而我只初始化了_p1输出属性p就会有值.在子类想使用父类的带"_"实例变量时通常可以用这个方法(所以子类并不拥有父类的实例变量而是能通过调用父类的方法获取实例变量).

    四 @dynamic

    dynamic 的作用是告诉编译器:某个属性的setter和getter方法有开发者自己实现.如图运行代码发生了崩溃原因是没有找到属性p的setter方法.

    五  weak

    用weak修饰一个属性p,对象_p在被初始化一次(引用一次)后 在输出对象的值以为null,对象的地址也已经被回收了.调用对象的方法也没有发生任何事情,编译器默认对一个已经完全被释放的对象发送消息不会崩溃.

    六 assign

    assign修饰属性p,在初始化引用一次p后,打印_p的地址发现,地址没有被回收.但是打印对象的值时发生了错误,原因是编译器通过内存地址找不到该地址下的值.也就是他已经被置为了空,但内存地址还在.


    苹果的垃圾回收机制都是根据对象的引用计数来判断的,当一个对象的引用计数为0时,系统就会立刻清除这个对象.而基本数据类型的初始化和使用都是在内存中进行的所以用assign来修饰.如图用assig修饰字符串类型的p在初始化引用一次后仍可使用它.

    七 strong

    用strong修饰的对象,在被引用一次后不会立刻被释放.当我们手动将它置为nil时它的内存地址会立刻被回收.所以我们经常用strong来修饰对象.

    八 copy

    1.首先用strong修饰一个属性可变字符串string,

    2.初始化一个实例变量然后将它赋值给string发现两个变量的地址是一样.

    3.这时候改变a的值,注意不要用"="否则想当于重新初始化了a,这样a就不是原来的a.

    4.打印发现两者变量的值时一样的.因为编译器是通过内存地址来寻找值的.而他们的内存地址是一样的所以查找到的是同一个值.

    5.如果我们再改变_string的值a又会怎么样呢?

    再给_string拼接一断字符串,发现a的值也跟着变了.这也进一步验证了我们第4步得出的结论

    6. 把strong改成copy

    发现给用copy修的string赋值后.string的内存地址和a的地址不同.我们改变a的值_string的值不会改变,因为它们的内存地址指向不同的值.这就是深拷贝

    7. 如果我们用copy修饰一个不可变的属性呢?

    如图发现a的地址的string的地址是一样的他没有拷贝内存地址,此时就是浅拷贝.所以以后在做属性传知的时候就要注意了.

    九 mutableCopy

    1. 首先用copy修饰一个可变字符串_string然后去改变_string的值发现出现了崩溃,原因是不能调用_string的appendString方法.

    2. 那么该如何改变_string的值呢?

    由于mutableCopy不能像copy那样在声明属性时使用,所以只能通过调用方法来修饰.如图通过调用mutableCopy赋值后,a和_string的内存地址是不一样的.两个变量的值互不影响.又产生了深拷贝.

    3.如果我们用mutableCopy拷贝一个不可变的字符串又会怎样呢?

    如图我们将a变成不可变字符串类型,发现a的地址和_string的地址仍是不一样的,所以我们对一个不可变的字符串做mutableCopy操作仍是深拷贝.

    十 不完全深拷贝

    前面都是对字符串类型做拷贝操作如果对集合类拷贝会有什么效果呢?

    1. 如图对不可变数组a分别进行copy和mutableCopy操作,发现和拷贝字符串类型时一样,a和b的地址是一样的,c的地址与前两者不同.

    2.

    3.这时候我们将不可变数组改成可变数组类型,发现仍和字符串类型时一样,abc三个内存地址都不相同,改变a的值其他两个不变.

    4.如果我们改变其中的元素string那么b和c还会不受影响吗?

    在改变元素string后我们发现b和c中的元素也受到了影响,也就是说虽然b和c只是深拷贝了对象a,而没有对数组a中的元素进行深拷贝,所以数组中的元素地址的仍和原来相同指向同一片内存区域.这就是不完全深拷贝.

    相关文章

      网友评论

        本文标题:iOS 有趣的属性修饰符和拷贝

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