readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak属性的作用分别是什么。
关键字注释
readwrite此标记说明属性会被当成读写的,这也是默认属性。
readonly此标记说明属性只可以读,也就是不能设置,可以获取。
assign不会使引用计数加1,也就是直接赋值。
retain会使引用计数加1。
copy建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝。
nonatomic非原子性访问,多线程并发访问会提高性能。
atomic原子性访问。
strong打开ARC时才会使用,相当于retain。
weak打开ARC时才会使用,相当于assign,可以把对应的指针变量置为nil。
为什么代理要用weak?
首先明白什么情况使用 weak 关键字?
在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决
delegate 代理属性,代理属性也可使用
assign自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用 weak
自定义IBOutlet 控件属性一般也使用weak;当然,也可以使用 strong,但是建议使用 weak
weak 在属性所指的对象遭到摧毁时,系统会将 weak 修饰的属性对象的指针指向 nil,在 OC 给 nil 发消息是不会有什么问题的;如果使用 assign 策略在属性所指的对象遭到摧毁时,属性对象指针还指向原来的对象,由于对象已经被销毁,这时候就产生了野指针,如果这时候在给此对象发送消息,很容造成程序奔溃assigin 可以用于修饰非 OC 对象,而 weak 必须用于 OC 对象。
block和代理的区别?
block 和 delegate 都可以通知外面。block 更轻型,使用更简单,能够直接访问上下文,这样类中不需要存储临时数据,使用 block 的代码通常会在同一个地方,这样读代码也连贯。delegate 更重一些,需要实现接口,它的方法分离开来,很多时候需要存储一些临时数据,另外相关的代码会被分离到各处,没有 block 好读。
应该优先使用 block。而有两个情况可以考虑 delegate。
1. 有多个相关方法。假如每个方法都设置一个 block, 这样会更麻烦。而 delegate 让多个方法分成一组,只需要设置一次,就可以多次回调。当多于 3 个方法时就应该优先采用 delegate。
2. 为了避免循环引用,也可以使用 delegate。使用 block 时稍微不注意就形成循环引用,导致对象释放不了。这种循环引用,一旦出现就比较难检查出来。而 delegate 的方法是分离开的,并不会引用上下文,因此会更安全些。
将 block 简单分类,有三种情形。
* 临时性的,只用在栈当中,不会存储起来。比如数组的 foreach 遍历,这个遍历用到的 block 是临时的,不会存储起来。
* 需要存储起来,但只会调用一次,或者有一个完成时期。比如一个 UIView 的动画,动画完成之后,需要使用 block 通知外面,一旦调用 block 之后,这个 block 就可以删掉。
* 需要存储起来,可能会调用多次。比如按钮的点击事件,假如采用 block 实现,这种 block 就需要长期存储,并且会调用多次。调用之后,block 也不可以删除,可能还有下一次按钮的点击。
对于临时性的,只在栈中使用的 block, 没有循环引用问题,block 会自动释放。而只调用一次的 block,需要看内部的实现,正确的实现应该是 block 调用之后,马上赋值为空,这样 block 也会释放,同样不会循环引用。而多次调用时,block 需要长期存储,就很容易出现循环引用问题。
Cocoa 中的 API 设计也是这样的,临时性的,只会调用一次的,采用 block。而多次调用的,并不会使用 block。比如按钮事件,就使用 target-action,有些库将按钮事件从 target-action 封装成 block 接口, 反而容易出问题。
网友评论