一、为什么NSArray、NSDictionary、NSString声明的时候要使用copy修饰?
- 在OC中,父类指针可以指向子类,NSArray、NSDictionay这些都有一个可变的子类,使用copy修饰,可以使得当这些不可变的指针指向子类的时候,我们改变子类(可变的)的值,不会对父类指针产生影响。如果我们使用的是strong修饰,当我改变子类的值的时候,父类对象也会发生变化。
二、深拷贝和浅拷贝
深拷贝:内容的拷贝,地址不一样
浅拷贝:地址的拷贝。一样的地址
三、block使用copy修饰
因为方法内部的block变量是放在栈区的,使用copy,会将变量拷贝到堆区。在ARC中,系统会自动将block变量拷贝到堆区,所以使用copy和strong是一样的。
- 那么为什么,block变量要拷贝到堆区呢?
这是因为,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。他本身的作用域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。
使用retain也可以,但是block的retain行为默认是用copy的行为实现的,
因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
- 这里补充一个block引起的循环引用的问题解决方式(使用__weak声明)
__weak CurrentViewController *blockSelf = self;
brush.getCardInfo=^(NSDictionary *info){
[blockSelf test];
};