iOS - 屬性關(guān)鍵字的使用

作者:Mitchell 

一、 assign###

  • ‘基本數(shù)據(jù)類型’、‘枚舉’、‘結(jié)構(gòu)體’ 等非OC對象類型

二、 weak

  • 一般應(yīng)用: UI控件

  • 詳細說明:

    • 為什么建議UI控件一般使用weak?首先我們從controller來看,controller是被系統(tǒng)用強指針引用著,所以如果 controller 還存在,里面的子控件也會存在,那么controller 強引用著它的view(從 controller 中它的 view 的屬性是 retain 看出來的,retain 就是 MRC 年代的強引用),那么 view 又強引用著它的數(shù)組對象subviews,數(shù)組對象又引用著它所包含的數(shù)組內(nèi)容,所以當我們創(chuàng)建出來一個UI控件并將其加入到subviews的時候,它就會被一個強指針所引用著,我們可以簡化一下這個過程:--> Controller --> View --> Subviews(數(shù)組) --> 數(shù)組內(nèi)容(添加到其中的UI控件)
    • 清楚了過程之后,我們來看我們所創(chuàng)建的對象,如果我們所創(chuàng)建的是一個臨時變量的話,那么當出去作用域之后對象就被銷毀,但是這里請注意,這里分為兩個內(nèi)存空間,一個是對象的內(nèi)存空間,一個是指針的內(nèi)存空間,如果創(chuàng)建的是臨時變量的話,一旦出了作用域那么我們的指針內(nèi)存是被清空了,但是我們的內(nèi)容如果加到了subviews中,就會被subviews強引用,那么我們的控件就還會存在,只不過是一個指向它的指針被清空了而已。
    • 回過頭我們說說全局變量,全局變量的話,指針會一直存在,這里面談?wù)劄槭裁匆脀eak,其實只要我們創(chuàng)建的控件加入到subviews中去的話,那么這個控件就會一直存在,所以在這里我們所創(chuàng)建的指針是weak或strong其實只不過是多一個實線虛線的問題,也就是控件已經(jīng)被強引用了,你再給它添加一個強引用或者弱引用在使用上都不會有什么問題,但是問題來了,如果我們remove了這個控件,我們subViews中的那根線被切斷,也就是這個代表我不再需要這個控件了,那么這個時候如果再用一個strong來連接它,那么對象就不會被清除,既然我們都不需要它了,為什么我還強引用它?這也就是為什么我們再這里用弱引用的原因。`簡言之,就是內(nèi)存使用上的合理性,當這個控件我們需要的時候其實已經(jīng)有一個強引用在引用著它,我們沒有必要再弄一根指針來強引用著它,當我們不需要它的時候,如果是weak的話自然而然直接釋放掉了,如果strong的話還會保留它,既然我們沒用了我們?yōu)槭裁催€要留著它而占用我們寶貴的內(nèi)存呢?我們也可以看一下這張圖片用來理解:


      圖1.1.png
    • 這里特殊說一下IBOutlet中的拖線創(chuàng)建,我們可以發(fā)現(xiàn),如果用storyboard或者xib進行的脫線創(chuàng)建,蘋果都會自動降屬性置為weak,這種做法似乎也符合我們之前的說法,但是蘋果又會在之前加了一個IBOutlet這個關(guān)鍵詞,那么這個詞是什么意思呢?我們看一下蘋果的官網(wǎng)解釋: The symbol IBOutlet is used only by Xcode, to determine when a property is an outlet; it has no actual value. 意思很清楚了,它僅僅是指定了一個屬性是一個 外部設(shè)置的,并沒有實質(zhì)的含義,通常與外界連接是通過當前的 viewcontroller 。那么在引用上又有什么不同呢?在官方文檔中是這么說的,在我們創(chuàng)建了IBOutlet之后,我們系統(tǒng)會有一個自動對它進行一個強引用,也就是又多了一條實線連接著它,當控件從我們的subviews中移除之后,這條線會自動判斷去留,也就是不會對我們的內(nèi)存的性能造成影響,該在的時候我在,該消失的時候自己就會消失了。這里也用一張圖來說明:
      圖1.2.png

    在我寫demo的時候有一點需要注意,就是當我們將控件從subViews中remove調(diào)之后,這個時候打印指針還存在,說明指針并不會馬上銷毀,而是進行下一輪消息循環(huán)之后才會發(fā)現(xiàn)這個指針被銷毀了

  • 總結(jié):
    我們首先是從內(nèi)存的利用上,我們建議對UI控件采用weak,其次是觀察蘋果的聲明方式,依然是建議使用weak,因為標準都是參考于蘋果,而且合理性也擺在那里,為什么不用呢?


三、 strong

  • OC對象類型(NSArray、NSDate、NSNumber、模型類)
  • 一個對象只要有強指針引用著,就不會被銷毀

四、 copy

  • 一般用在NSString*類型、block類型上
  • copy語法的作用:
    • 產(chǎn)生副本
      • copy返回的是不可變的副本
      • mutableCopy返回的是可變的副本
      • copy與mutableCopy的區(qū)別我已經(jīng)在這篇文章中給了詳細的介紹。
    • 修改了副本并不會影響源對象,修改了源對象,并不會影響副本。
  • copy在屬性聲明中的使用,直接舉例說明
@interface ViewController ()
//注意這里雖然是copy的屬性,但是我們這個指針還是強引用的
@property(nonatomic,copy)NSString*name;
@end
@implementation Viewcontroller
 -(void)viewDidLoad{
    [self viewDidLoad];
    NSMutableString*str = [NSMutableString stringWithFormat:@"aaa"];
    self.name = str;
    [str appendString:@"bbb"];
    NSLog(@"str= %@",str);
    NSLog(@"name = %@",self.name);
    NSLog(@"%p,%p",str,self.name);
}
@end

我們來看一下說出的結(jié)果:
- str = aaabbb
- name = aaa
- 輸出的內(nèi)存地址:0x7f90f3028180 , 0x7f90f3027450
- 這說明了這個copy的含義就是,我們在給name屬性賦值的時候,,系統(tǒng)默認先將str執(zhí)行一次copy方法,然后再將結(jié)果賦給我們的屬性,只有這樣你再之后對str修改之后,name的值還是不變的,說明兩個指針其實指向的是不同的內(nèi)容,之后我們又打印了我們的指針值,得出不同的結(jié)果又證明了上述所說。
- 注意:并不是所有情況下我們的string都必須使用copy,因為如果我們的需求是希望string是隨著我的改變而改變的,那么這個時候應(yīng)該使用strong。

  • 類的copy:
    • 如果我們想實現(xiàn)類的copy,必須實現(xiàn)一個方法:-(id)copyWithZome:(NSZone*)zone; 這是為什么呢?我們?nèi)?NSString 中去尋找答案,那么我們會發(fā)現(xiàn)其實 NSString 已經(jīng)遵守了 NSCopying 與 NSMutableCopying 的協(xié)議,我們主要看 NSCopying ,進入這個協(xié)議之后你會發(fā)現(xiàn) -(id)copyWithZome:(NSZone*)zone 這個方法,也就是說NSString 已經(jīng)遵守了協(xié)議的這個方法,所以才能直接實現(xiàn) copy 的方法。所以如果想實現(xiàn)自定義類的 copy 方法,我們是需要先遵守 NSCopying 協(xié)議,然后實現(xiàn)-(id)copyWithZome:(NSZone*)zone的方法:
   -(id)copyWithZone:(NSZone *)zone{
    Mitchell*copyMit = [[Mitchell allocWithZone:zone] init];
    copyMit.name = self.name;
    return copyMit;
}
- zone:系統(tǒng)返回給我們 copy 對象的內(nèi)存空間
- 注意:必須在初始化方法中給屬性賦值,才能讓 copy 出的對象和原來的對象有相同的屬性。
  • 再說一下 copy 類中的 set 方法,如果屬性是 copy 的,那么系統(tǒng)默認只會在 set 方法中調(diào)用 copy 的方法:
-(void)setName;(Mitchell*)name{
    _name = [name copy];
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容