系列:iOS開發(fā)-strong 、weak、copy 、assign 、retain
無論是在iOS開發(fā)剛學(xué)習(xí)的時候,還是在日常的開發(fā)中,我們都需要創(chuàng)建的對象,對應(yīng)的我們就會有設(shè)置對象的類型的必要.
這個并不是說設(shè)置了就完事了,為什么我們要用strong 、weak、copy 、assign 、retain等這些不同的修飾詞類定義對象呢?
說白了就是為了內(nèi)存管理.
內(nèi)存管理是我們做開發(fā)的所必須要時刻關(guān)注的問題.
好在iOS開發(fā)經(jīng)過這么久的發(fā)展,已經(jīng)經(jīng)過了MRC的時代.現(xiàn)在的ARC時代系統(tǒng)自動管理內(nèi)存,讓我們省掉了很多事情,但是我們?nèi)匀坏囊P(guān)注,我們需要在適當(dāng)?shù)牡胤绞褂眠m當(dāng)?shù)念愋?避免造成不必要的內(nèi)存消耗,或者循環(huán)引用等問題.
copy: 用于希望保持一份傳入值的拷貝,而不是值自身的情況,即把原來的對象完整的賦值到另外一地方,重新加載一內(nèi)存區(qū),一個地方變了不影響另一個地方的對象。
assign: 簡單的直接賦值,相當(dāng)于說兩個對象指向同個內(nèi)存區(qū),一個地方的變了,其他的也跟著改變。
retain:釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數(shù) 為1
strong 用來修飾強(qiáng)引用的屬性;類似于對應(yīng)原來的retain或者copy
weak 用來修飾弱引用的屬性;類似于對應(yīng)原來的assign
copy與retain:
1、copy其實是建立了一個相同的對象,而retain不是;
2、copy是內(nèi)容拷貝,retain是指針拷貝;
3、copy是內(nèi)容的拷貝 ,對于像NSString,的確是這樣,但是如果copy的是一個NSArray呢?這時只是copy了指向array中相對應(yīng)元素的指針.這便是所謂的"淺復(fù)制".
4、copy的情況:NSString *newPt = [pt copy];
此時會在堆上重新開辟一段內(nèi)存存放@"abc" 比如0X1122 內(nèi)容為@"abc 同時會在棧上為newPt分配空間 比如地址:0Xaacc 內(nèi)容為0X1122 因此retainCount增加1供newPt來管理0X1122這段內(nèi)存;
assign與retain:
1、assign: 簡單賦值,不更改索引計數(shù);
2、assign的情況:NSString *newPt = [pt assing];
此時newPt和pt完全相同 地址都是0Xaaaa 內(nèi)容為0X1111 即newPt只是pt的別名,對任何一個操作就等于對另一個操作, 因此retainCount不需要增加;
3、assign就是直接賦值;
4、retain使用了引用計數(shù),retain引起引用計數(shù)加1, release引起引用計數(shù)減1,當(dāng)引用計數(shù)為0時,dealloc函數(shù)被調(diào)用,內(nèi)存被回收;
5、retain的情況:NSString *newPt = [pt retain];
此時newPt的地址不再為0Xaaaa,可能為0Xaabb 但是內(nèi)容依然為0X1111。 因此newPt 和 pt 都可以管理"abc"所在的內(nèi)存,因此 retainCount需要增加1 ;
assign與weak:
1、assign修飾的是基本數(shù)據(jù)類型,weak修飾的是對象類型
2、weak比assign多了一個功能就是當(dāng)屬性所指向的對象消失的時候(也就是內(nèi)存引用計數(shù)為0)會自動賦值為nil,這樣再向weak修飾的屬性發(fā)送消息就不會導(dǎo)致野指針操作crash,而assign并不會賦值nil,也就是我們通常說的野指針
3、在MRC時代,我們使用代理的時候是使用的assign,ARC的時代我們更傾向于你使用weak,
strong與weak:
1、strong與weak是由ARC新引入的對象變量屬性
ARC引入了新的對象的新生命周期限定,即零弱引用。如果零弱引用指向的對象被deallocated的話,零弱引用的對象會被自動設(shè)置為nil。
2、通常我們手動創(chuàng)建一個對象的時候我們會在vc中創(chuàng)建一個strong類型的對象,
表示當(dāng)前的vc的類的對象擁有這個小的對象,這樣其可以對該對象保持所有權(quán),該對象的修改乃至銷毀都由當(dāng)前的vc來決定,當(dāng)vc不存在的時候?qū)ο笠矔会尫?br>
3、我們會在使用xib或者storyboard的時候,拖出來的是一個weak類型的對象,事實上IBOutlet的屬性一般可以設(shè)為weak是因為它已經(jīng)被view引用了,除非view被釋放,否則IBOutlet的屬性也不會被釋放,另外IBOutlet屬性的生命周期和view應(yīng)該是一致的,所以IBOutlet屬性一般設(shè)為weak。
4、在ARC的項目中,我們絕大部分看到的都是strong和weak修飾數(shù)據(jù)類型,我們更少的管理對象的內(nèi)存釋放問題.但是我們必須注意,比如一個NSTimer對象,通常我們使用strong,但是我們?nèi)绻褂貌划?dāng),我們就會造成其無法釋放,從而導(dǎo)致vc無法釋放的問題,這個你可以查找一些資料看看
5、在使用block的時候我們也會遇到循環(huán)引用導(dǎo)致的無法釋放的問題
例如vc中有一個block,在block中直接調(diào)用vc中的一個對象.就會造成循環(huán)引用.
我們需要學(xué)會使用弱指針 __weak 來解決,后續(xù)的博客會單獨介紹
6、strong強(qiáng)引用也就是我們通常所講的引用,其存亡直接決定了所指對象的存亡。如果不存在指向一個對象的引用,并且此對象不再顯示列表中,則此對象會被從內(nèi)存中釋放。
7、weak弱引用除了不決定對象的存亡外,其他與強(qiáng)引用相同。即使一個對象被持有無數(shù)個若引用,只要沒有強(qiáng)引用指向他,那麼其還是會被清除。沒辦法,還是 “強(qiáng)哥” 有面子。
strong與retain:
1、聲明屬性時用strong或者retain效果是一樣的(貌似更多開發(fā)者更傾向于用strong)
2、在聲明Block時,使用strong和retain會有截然不同的效果。strong會等于copy,而retain竟然等于assign!
3、定義Block還是應(yīng)該用copy因為非ARC下不copy的Block會在棧中,ARC中的Block都會在堆上的。
暫時只想到這么多,后續(xù)會繼續(xù)添加