@property 后面可以有哪些修饰符?
1.线程安全的: atomic, nonatomic
2.访问权限的: readonly, readwrite
3.内存管理(ARC) assign,strong,weak,copy
4.内存管理(MRC)assign, retain,copy
5.指定方法名称: setter= getter=
什么情况使用 weak 关键字,相比 assign 有什么不同?怎么用 copy 关键字?
在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如: delegate 代理属性
自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用 weak,自定义 IBOutlet 控件属性一般也使用 weak;当然,也可以使用strong
不同点:
weak 此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。 而 assign 的“设置方法”只会执行针对“纯量类型” (scalar type,例如 CGFloat 或 NSlnteger 等)的简单赋值操作。
assigin 可以用非 OC 对象,而 weak 必须用于 OC 对象
copy用途:
NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;
block 也经常使用 copy 关键字
block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。
下面做下解释: copy 此特质所表达的所属关系与 strong 类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为 NSString 时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个 NSMutableString 类的实例。这个类是 NSString 的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。
用 @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
用@property (copy) NSMutableArray *array;会有什么问题?
我们县回忆一下copy属性的作用,一个属性标记了copy,当你调用他的setter方法,他会建立一个索引计数为1的对象,然后释放旧对象。
@property (copy) NSMutableArray * a;
NSMutableArray* b = [NSMutableArray array];
a = b;
等同于
@property (strong) NSMutableArray * a;
NSMutableArray* b = [NSMutableArray array];
a = [b copy];
所以你的a根本就是一个NSArray,所以报了
-[__NSArray0 removeAllObjects]: unrecognized selector sent to instance 0x14e14970
未找到实例方法的错误。因为NSArray没有removeAllObjects方法。
正确的写法应该是不用copy属性
@property (strong) NSMutableArray * a;
NSMutableArray* b = [NSMutableArray array];
a = [b mutableCopy];
这里的b可以是NSMutableArray也可以是NSArray;