Objective-C中類的成員變數與屬性

來源:互聯網
上載者:User

標籤:objective-c   屬性   成員變數   類   

在Objective-C的類與對象的概念中. 成員變數與屬性的區別與聯絡一直沒有搞清楚. 直到學習了慕課網上的這個課程Objective-C物件導向初體驗, 才算真正有了點感覺了. 最關鍵的結論就是: 類內使用成員變數{}, 類外使用屬性@property.

成員變數成員變數及其get方法.

首先, 我們來看下基本的類成員變數及其使用.

// People.h@interface People : NSObject{    NSString *_peopleName;}@end

在.m中不做任何事情, 然後在main.m調用_peopleName成員變數,
(可以看出, 調用類的成員變數時, 使用 . 文法符號會出錯, 必須使用->來調用):
調用類成員變數" title="">
改為->, 調用p1->_peopleName的結果如下:

即, 該_peopleName預設是protected, 外部調用需要設定為@public. 改動一下:

// People.h@interface People : NSObject{    @public    NSString *_peopleName;}@end

調用p1->_peopleName的結果如下:

2015-05-06 15:58:41.039 memberAndProperty[2851:304100] p1._peopleName : (null)
類內部使用成員變數

如果想在init中初始化_peopleName, 則在People.m中:

// People.m- (instancetype)init{    self = [super init];    if (self) {        _peopleName = @"people name 1";    }    return self;}

調用p1->_peopleName的結果如下:

2015-05-06 16:01:36.974 memberAndProperty[2895:306281] p1._peopleName : people name 1

其他使用該成員變數的類內部方法都是類似的用法.

set方法

以上是對類成員變數_peopleName的調用, 如果想要對其附新值呢?

        // main.m        People *p1 = [[People alloc] init];        NSLog(@"p1._peopleName : %@", p1->_peopleName);        p1->_peopleName = @"people name 2";        NSLog(@"p1._peopleName : %@", p1->_peopleName);

結果:

2015-05-06 16:05:34.915 memberAndProperty[2931:309406] p1._peopleName : people name 12015-05-06 16:05:34.916 memberAndProperty[2931:309406] p1._peopleName : people name 2

以上可見, 將_peopleName設定為@public之後, 可在類外對其進行get/set操作, 直接調用或賦值即可.
不推薦使用p1->_peopleName這樣的形式. 因為, 這樣就不符合我們所說的
“類內使用成員變數{}, 類外使用屬性@property“的結論了. 且將成員變數_peopleName設為@public會很不安全.

自訂成員變數的get/set方法

仍然將成員變數_peopleName預設為@protected, 從類內部的方法中對_peopleName進行讀取或賦值, 然後間接傳遞至類外部, 是一個不錯的選擇.
首先, 在.h中聲明getName和setName方法:

// People.h@interface People : NSObject{    NSString *_peopleName;}-(NSString *)getName;-(void)setName:(NSString *)name;@end

在.m中, get/set這兩個方法是以在類內部對成員變數_peopleName進行調用或賦值的方式來實現的.

// People.m-(NSString *)getName {    return _peopleName;}-(void)setName:(NSString *)name {    _peopleName = name;}

那麼, 調用的時候就非常方便了:

        // main.m        People *p1 = [[People alloc] init];        NSLog(@"p1.getName : %@", p1.getName);        [p1 setName:@"people name 2"];        NSLog(@"p1.getName : %@", p1.getName);

結果如下:

2015-05-06 16:25:36.019 memberAndProperty[3036:320317] p1.getName : people name 12015-05-06 16:25:36.020 memberAndProperty[3036:320317] p1.getName : people name 2

使用自訂的get/set, 從類內部調用成員變數是一種比較常見的方式. 但需手動添加這兩個方法.

屬性

那麼, 有沒有更加簡便的方法呢? 或者說, get/set這種非常常見的操作, 能不能預設提供給我們呢? 答案是肯定的!
在新的iOS SDK中, 使用@property來定義類的屬性, 是專用於從類外部對其進行調用或賦值的.
在.h中先聲明peopleName屬性:

// People.h@interface People : NSObject{    NSString *_peopleName;}@property(nonatomic, strong) NSString *peopleName;// nonatomic 非原子性訪問, 不加同步機制, 多線程並非訪問時可提高效能// strong 相當於一個深拷貝的操作@end

在.m中使用@synthesize指令將peopleName屬性與_peopleName成員變數關聯起來:

// People.m@implementation People@synthesize peopleName = _peopleName;- (instancetype)init{    self = [super init];    if (self) {        _peopleName = @"people name 1";    }    return self;}@end

即, 編譯器遇到@synthesize peopleName = _peopleName;時, 會自動產生對peopleName的get/set方法.
且這裡的底線_是必不可少的, 否則就不能正確地將屬性與成員變數關聯起來.
然後, 我們直接調用即可:

        // main.m        People *p1 = [[People alloc] init];                 NSLog(@"p1.peopleName : %@", p1.peopleName);        p1.peopleName = @"people name 2";        NSLog(@"p1.peopleName : %@", p1.peopleName);

結果如下:

2015-05-06 16:32:29.142 memberAndProperty[3094:325295] p1.peopleName : people name 12015-05-06 16:32:29.143 memberAndProperty[3094:325295] p1.peopleName : people name 2

實際上, 編譯器比我們想象中更聰明, 在.h檔案中的{ NSString *_peopleName; }這個成員變數不需要聲明也可以. 僅僅聲明了@property(nonatomic, strong) NSString *peopleName;這個屬性, xcode也會預設自動為我們聲明一個該類的peopleName成員變數, 及隱藏的get/set方法. 這裡, 就體現出了底線 的作用了.

結論

結論依然是: 類內使用成員變數{}, 類外使用屬性@property.
因此在類外的話, 強烈推薦使用屬性@property.
而如果非要在類外使用成員變數{}, 則要麼將該成員變數設為@public, 要麼自訂其get/set方法, 利用這兩個方法從類內部對成員變數進行調用或賦值. 這兩種方法各自的弊端及使用請參考以上內容.

Objective-C中類的成員變數與屬性

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.