iOS 中利用strong,copy,assign,weak修飾變數的異同點
ARC中
在iOS開發中定義@property屬性時,經常用到assign、weak、strong、copy等關鍵字。我們經常會考慮在何時應該使用哪個關鍵字,尤其是在面試的時候,經常會被問到這些關鍵字之間的區別,下面詳細和大家探討一下:
assign:用於對基本資料型別進行賦值操作,不更改引用計數。也可以用來修飾物件,但是,被assign修飾的物件在釋放後,指標的地址還是存在的,也就是說指標並沒有被置為nil,成為野指標。如果後續在分配物件到堆上的某塊記憶體時,正好分到這塊地址,程式就會crash。之所以可以修飾基本資料型別,因為基本資料型別一般分配在棧上,棧的記憶體會由系統自動處理,不會造成野指標。
weak:修飾Object型別,修飾的物件在釋放後,指標地址會被置為nil,是一種弱引用。
delegate為何要用weak修飾:
在ARC環境下,為避免迴圈引用,往往會把delegate屬性用weak修飾;在MRC下使用assign修飾。weak和strong不同的是:當一個物件不再有strong型別的指標指向它的時候,它就會被釋放,即使還有weak型指標指向它,那麼這些weak型指標也將被清除。
ARC下的strong等同於MRC下的retain都會把物件引用計數加1。
copy:會在記憶體裡拷貝一份物件,兩個指標指向不同的記憶體地址。一般用來修飾NSString等有對應可變型別的物件,因為他們有可能和對應的可變型別(NSMutableString)之間進行賦值操作,為確保物件中的字串不被修改 ,應該在設定屬性是拷貝一份。而若用strong修飾,如果物件在外部被修改了,會影響到屬性。
block屬性為什麼需要用copy來修飾?
因為在MRC下,block在建立的時候,它的記憶體是分配在棧(stack)上的,而不是在堆(heap)上,可能被隨時回收。他本身的作於域是屬於建立時候的作用域,一旦在建立時候的作用域外面呼叫block將導致程式崩潰。通過copy可以把block拷貝(copy)到堆,保證block的宣告域外使用。在ARC下寫不寫都行,編譯器會自動對block進行copy操作。
__block與__weak的區別
__block:在ARC和MRC下都可用,可修飾物件,也可以修飾基本資料型別。
__block物件可以在block被重新賦值,__weak不可以。
__weak:只在ARC中使用,只能修飾物件,不能修飾基本資料型別(int、bool)。
同時,在ARC下,要避免block出現迴圈引用,經常會:__weak typedof(self) weakSelf = self;