iOS中的关键字,深拷贝和浅拷贝。

weak 和assign 的区别
weak修饰对象,assign可以修饰基本数据类型和对象 不过weak修饰对象,对象释放后weak会置为nil assign还是会这个对象的地址 出现野指针

block为什么使用copy
MRC下声明创建block,block会存放在栈中 需要copy修饰 存放到堆中 因为存放在栈中 block的生命周期会随着函数的结束出栈,此时再调用block 会崩溃 。拷贝的堆中就没事。ARC下写不写都行,ARC编译的时候会吧block放在堆中。

strong和retain
都是强引用 都会是引用计数加一 但是在声明block时不一样 声明block时 strong相当于copy retain相当assign

assign 用于基本数据类型 不改变引用计数 也可以修饰对象,但对象被释放后,指针的地址仍然是存在的 并没有置为nil 从而出现野指针 如果后面有对象正好分配到这一块地址上 就会Crash 之所以可以修饰基本数据类型 因为基本数据类型一般分配在栈上,栈的内存由系统自动处理,不会出现野指针。

weak 修饰对象 对象释放后,指针地址会被置为nil,不会产生野指针,是一种弱引用。在ARC下避免循环引用,delegate属性用weak修饰

__block 修饰对象 对象可以在block被重新赋值 可以修饰对象 也可以修饰基本数据类型

__weak 只在ARC下使用 只能修饰对象,弱引用 避免block循环引用。 假设一种情况,在 block代码块中 10秒后执行。在10秒前推出了控制器,此时会走dealloc方法,block就无法执行。 避免因为对象被销毁无法执行,应该在block中再次__strong强引用,retain引用计数加一,此时block仍然会执行,执行完成后才会走dealloc。

copy会在内存中拷贝一份对象,深拷贝和浅拷贝。
用copy修饰时 将可变的赋值给对象时,会先copy出一个不可变的副本,然后指针指向这个不可变的副本的内存地址。
如果用不可变的给对象赋值 则直接指向这个不可变的对象的内存地址。

用strong修饰时 将一个可变的赋值给对象时,并不会拷贝,而是直接指向这个可变的对象的内存地址。

copy和strong修饰字符串的区别
创建一个不可变字符串 使用不可变的NSString进行赋值 copy和strong没有区别 都是指向这个不可变的NSString的内存地址。
但使用可变的MSrting赋值时 copy会拷贝一个副本 然后指向这个副本 但是strong仍然会直接指向这个可变的MString, 因此如果此时修改MString的话,用strong修饰的字符串也会随之改变。但本身时创建的不可变字符串,所以用strong达不到要求。因此创建不可变字符串的时候用copy修饰。

可变字符串用strong去修饰 不可变字符串用copy去修饰
可变对象用strong去修饰,例如可变数组。不可变对象用copy修饰,例如不可变数组。

copy 与 mutableCopy 的区别
简单讲 copy就是拷贝出一份不可变的副本 mutableCopy就是拷贝出一份可变的副本
copy作用在一个不可变对象上的时候 不会拷贝一份不可变对象
mutableCopy作用在一个不可变的对象上的时候 就会拷贝出一份可变的对象,赋值时指向这个可变的对象。

copy作用在一个可变对象上的时候 会拷贝出一份不可变的对象 赋值时指向这个不可变的对象
mutableCopy作用在一个可变对象上的时候 会拷贝出一份可变的对象,赋值时指向这个可变的对象。

copy和mutableCopy作用在一个不可变的对象集合时,copy是浅拷贝,mutaleCopy是深拷贝,又拷贝出了新的对象。内部元素仅发生了浅拷贝,只拷贝了引用,内部元素存放的地址还原来的地址。

copy和mutableCopy作用在一个可变的对象集合时,虽然产生了一个副本,但内部元素仅发生了浅拷贝,只拷贝了引用,内部元素存放的地址还原来的地址。

浅拷贝只是拷贝了引用 深拷贝则整个对象包括内部元素都不一样

作用于集合类对象 无论是copy还时mutableCopy 区别仅仅在于copy产生了一个副本时不可变的,mutableCopy产生的副本时可变的 但是 内部元素都只是引用 并没有发生深拷贝

你可能感兴趣的:(iOS中的关键字,深拷贝和浅拷贝。)