1.assign 與weak區(qū)別
assign適用于基本數(shù)據(jù)類型,weak是適用于NSObject對象,并且是一個弱引用。
assign其實也可以用來修飾對象。那么我們?yōu)槭裁床挥盟揎棇ο竽兀恳驗楸籥ssign修飾的對象(一般編譯的時候會產(chǎn)生警告:Assigning retained object to unsafe property; object will be released after assignment)在釋放之后,指針的地址還是存在的,也就是說指針并沒有被置為nil,造成野指針。對象一般分配在堆上的某塊內(nèi)存,如果在后續(xù)的內(nèi)存分配中,剛好分到了這塊地址,程序就會崩潰掉。
那為什么可以用assign修飾基本數(shù)據(jù)類型?因為基礎(chǔ)數(shù)據(jù)類型一般分配在棧上,棧的內(nèi)存會由系統(tǒng)自己自動處理,不會造成野指針。
weak修飾的對象在釋放之后,指針地址會被置為nil。所以現(xiàn)在一般弱引用就是用weak。weak使用場景:
在ARC下,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用weak來解決,比如: delegate代理屬性,通常就會聲明為weak。
自身已經(jīng)對它進行一次強引用,沒有必要再強引用一次時也會使用weak。比如:自定義 IBOutlet控件屬性一般也使用weak,當然也可以使用strong。
2.strong 與copy的區(qū)別
strong 與copy都會使引用計數(shù)加1,但strong是兩個指針指向同一個內(nèi)存地址,copy會在內(nèi)存里拷貝一份對象,兩個指針指向不同的內(nèi)存地址
3.__block與__weak的區(qū)別
__block是用來修飾一個變量,這個變量就可以在block中被修改
__block:使用 __block修飾的變量在block代碼塊中會被retain(ARC下會retain,MRC下不會retain)
__weak:使用__weak修飾的變量不會在block代碼塊中被retain
同時,在ARC下,要避免block出現(xiàn)循環(huán)引用 __weak typedof(self)weakSelf = self;
4.1 block變量定義時為什么用copy?block是放在哪里的?
block本身是像對象一樣可以retain,和release。但是,block在創(chuàng)建的時候,它的內(nèi)存是分配在棧(stack)上,可能被隨時回收,而不是在堆(heap)上。他本身的作于域是屬于創(chuàng)建時候的作用域,一旦在創(chuàng)建時候的作用域外面調(diào)用block將導(dǎo)致程序崩潰。通過copy可以把block拷貝(copy)到堆,保證block的聲明域外使用。
特別需要注意的地方就是在把block放到集合類當中去的時候,如果直接把生成的block放入到集合類中,是無法在其他地方使用block,必須要對block進行copy。
[arrayaddObject:[[^{? ? NSLog(@"hello!");} copy] autorelease]];
4.2 block 為什么不用strong?
block如果用到了self,就會retain self,如果是strong的話,就造成了循環(huán)引用
官方文檔:You should specify copy as the property attribute, because a block needs to be copied to keep track of its captured state outside of the original scope.This isn’t something you need to worry about when using Automatic Reference Counting, as it will happen automatically, but it’s best practice for the property attribute to show the resultant behavior