一、為什么NSArray、NSDictionary、NSString聲明的時候要使用copy修飾?
- 在OC中,父類指針可以指向子類,NSArray、NSDictionay這些都有一個可變的子類,使用copy修飾,可以使得當這些不可變的指針指向子類的時候,我們改變子類(可變的)的值,不會對父類指針產(chǎn)生影響。如果我們使用的是strong修飾,當我改變子類的值的時候,父類對象也會發(fā)生變化。
二、深拷貝和淺拷貝
深拷貝:內(nèi)容的拷貝,地址不一樣
淺拷貝:地址的拷貝。一樣的地址
三、block使用copy修飾
因為方法內(nèi)部的block變量是放在棧區(qū)的,使用copy,會將變量拷貝到堆區(qū)。在ARC中,系統(tǒng)會自動將block變量拷貝到堆區(qū),所以使用copy和strong是一樣的。
- 那么為什么,block變量要拷貝到堆區(qū)呢?
這是因為,block在創(chuàng)建的時候,它的內(nèi)存是分配在棧(stack)上,而不是在堆(heap)上。他本身的作用域是屬于創(chuàng)建時候的作用域,一旦在創(chuàng)建時候的作用域外面調(diào)用block將導(dǎo)致程序崩潰。
使用retain也可以,但是block的retain行為默認是用copy的行為實現(xiàn)的,
因為block變量默認是聲明為棧變量的,為了能夠在block的聲明域外使用,所以要把block拷貝(copy)到堆,所以說為了block屬性聲明和實際的操作一致,最好聲明為copy。
- 這里補充一個block引起的循環(huán)引用的問題解決方式(使用__weak聲明)
__weak CurrentViewController *blockSelf = self;
brush.getCardInfo=^(NSDictionary *info){
[blockSelf test];
};