iOS 開發(fā):成員變量(屬性节芥,實(shí)例變量)的相關(guān)知識(shí)

1. 成員變量介紹

1. 成員變量解釋

我們把Objective-C中寫在類聲明的大括號(hào)中的變量稱之為成員變量(也稱為屬性蛤育,實(shí)例變量)。

  • 舉例:
@interface Iphone : NSObject
{
    // 成員變量聲明
    int _cpu;            // cup   0
    int _size;     // 尺寸  0
    int _color;          // 顏色  0

    // 其中_cpu、_size敲董、_color 就是 Iphone  類的成員變量
}

2. 成員變量特點(diǎn)

  • 成員變量只能通過對(duì)象來訪問
  • 成員變量不能離開類,離開類之后就不是成員變量
  • 成員變量不能再定義的同時(shí)進(jìn)行初始化
  • 成員變量存儲(chǔ)在當(dāng)前對(duì)象對(duì)應(yīng)的堆的存儲(chǔ)空間中慰安,不會(huì)被自動(dòng)釋放腋寨,只能手動(dòng)釋放
  • 成員變量前加下劃線"_"是蘋果的編程規(guī)范,或者說是程序員的習(xí)慣化焕。這樣寫的好處在下邊會(huì)提到

2. setter和getter方法

我們無法從外界(比如其他類和文件中)直接訪問定義在類中的成員變量萄窜。為了能夠從外界操作成員變量,我們需要為調(diào)用者提供相應(yīng)的方法來對(duì)成員變量進(jìn)行訪問撒桨、賦值等操作查刻。而定義這些方法都需要有一個(gè)有意義的名字,所以就有了getter-setter方法凤类。

getter-setter方法格式和寫法是固定的穗泵,這也是程序員之間的一種規(guī)范,只要有人想要訪問成員變量或給成員變量賦值谜疤,就會(huì)立刻想到getter-setter方法佃延,這樣就降低了程序員之間的溝通成本。

1. setter方法

  • 作用:用來設(shè)置成員變量夷磕,給成員變量賦值苇侵,可以在方法里面對(duì)變量進(jìn)行判斷,過濾掉一些不合理的值
  • 命名規(guī)范:
    • 必須是對(duì)象方法
    • 返回值類型為void
    • 方法名必須以set開頭企锌,而且后面跟上成員變量名去掉”_” 榆浓,首字母必須大寫
    • 必須提供一個(gè)參數(shù),參數(shù)類型必須與所對(duì)應(yīng)的成員變量的類型一致
    • 形參名稱和成員變量去掉下劃線相同
  • 舉例:

如:如果成員變量為int _size 那么與之對(duì)應(yīng)seter方法聲明為

-(void) setSize: (int) size;

  • setter方法的實(shí)現(xiàn)

- (void)setSize:(int)size;
{
     //成員變量以下劃線開頭的好處,就是可以區(qū)分局部變量和成員變量    
    _size = size;
}
  • setter方法的好處
    • 不讓數(shù)據(jù)暴露在外,保證了數(shù)據(jù)的安全性
    • 對(duì)設(shè)置的數(shù)據(jù)進(jìn)行判斷撕攒,過濾不合理的值(比如空值陡鹃、負(fù)數(shù)等等)

2. getter方法

  • 作用:為調(diào)用者返回對(duì)象內(nèi)部的成員變量的值烘浦,用來訪問成員變量
  • 命名規(guī)范:
    • 必須是對(duì)象方法
    • 必須有返回值,返回值的類型和成員變量的類型一致
    • 方法名必須是成員變量去掉下劃線
    • 一定是沒有參數(shù)的
  • 舉例

如:如果成員變量為int _size 那么與之對(duì)應(yīng)getter方法為

- (int) size;

  • getter方法的實(shí)現(xiàn)

- (int)size
{
    return _size;
}
  • getter方法的優(yōu)點(diǎn):

    • 可以讓我們?cè)谑褂胓etter方法獲取數(shù)據(jù)之前,對(duì)數(shù)據(jù)進(jìn)行加工
    • 比如雙十一活動(dòng),我們希望對(duì)全線商品的價(jià)格在原來的價(jià)格基礎(chǔ)上打五折萍鲸,那么我們只要去改成品類的價(jià)格的getter方法就可以了闷叉,讓他返回的值為價(jià)格 * 0.5

3. getter/setter方法注意

  • 在實(shí)際的開發(fā)中,setter和getter方法不一定都會(huì)提供脊阴。如果內(nèi)部的成員變量握侧,只允許外界讀取,但是不允許修改嘿期,則通常只提供getter方法而不提供setter方法
  • 成員變量名的命名以下劃線開頭品擎,setter和getter方法名不需要帶下劃線
  • 成員變量名使用下劃線開頭有兩個(gè)好處
    • 與getter方法的方法名區(qū)分開來
    • 可以和一些其他的局部變量區(qū)分開來,下劃線開頭的變量备徐,通常都是類的成員變量萄传。當(dāng)我看到以下劃線開頭變量,那么他一定是成員變量

3. 點(diǎn)語法

1. 點(diǎn)語法基本使用

如果給成員變量提供了getter和setter方法蜜猾,就可以通過點(diǎn)語法來訪問成員變量

2. 點(diǎn)語法的本質(zhì)

  • 其實(shí)點(diǎn)語法的本質(zhì)就是調(diào)用了setter方法和getter方法
  • 當(dāng)使用點(diǎn)語法時(shí)秀菱,編譯器會(huì)在程序翻譯成二進(jìn)制的時(shí)候?qū)?code>.語法自動(dòng)轉(zhuǎn)換為setter和getter方法
  • 如果點(diǎn)語法在=號(hào)左邊,那么編譯器會(huì)自動(dòng)轉(zhuǎn)換為setter方法
  • 如果點(diǎn)語法在=號(hào)右邊蹭睡,或者沒有等號(hào)衍菱,那么編譯器就會(huì)自動(dòng)轉(zhuǎn)換為getter方法

3. 點(diǎn)語法注意

  • 點(diǎn)語法的本質(zhì)是方法的調(diào)用,而不是訪問成員變量肩豁,當(dāng)使用點(diǎn)語法時(shí)脊串,編譯器會(huì)自動(dòng)展開成相應(yīng)的方法調(diào)用
  • 如果沒有setter和getter方法,則不能使用點(diǎn)語法
  • 不要在setter與getter方法中使用本屬性的點(diǎn)語法

- (void) setAge:(int)age {

    // 下面的代碼會(huì)引發(fā)死循環(huán)

    self.age = age;

    //編譯器展開后 [self setAge:age]

}

- (int) age {

    // 下面的代碼會(huì)引發(fā)死循環(huán)

    return self.age;

    // 編譯器展開后 [self   age]

}

4. 實(shí)例變量修飾符

1. 實(shí)例變量的作用域

  1. @public
    • 公開的
    • 在有對(duì)象的前下蓖救,任何地方都可以直接訪問
  2. @protected
    • 受保護(hù)的
    • 只能在當(dāng)前類和子類的對(duì)象方法中訪問
  3. @private
    • 私有的
    • 只能在當(dāng)前類的對(duì)象方法中才能直接訪問
  4. @package
    • 框架級(jí)別的
    • 作用域介于私有和公開之間洪规,只要處于同一個(gè)框架中相當(dāng)于@public,在框架外部相當(dāng)于@private
  • 舉例:

@interface Iphone : NSObject
{
    @public
    int _cpu;
    
    @private
    int _size;
    
    @protected
    int _color;
    
     @package
    double _weight;
}
@end

2. 變量修飾符的繼承和在子類中的訪問

修飾符 類別 能否繼承 在子類中的訪問
@private 私有成員 能被繼承 不能被外部方法訪問
@public 共有成員 能被繼承 不能被外部方法訪問
@protected 保護(hù)成員 能被繼承 不能被外部方法訪問

3. 實(shí)例變量作用域使用注意事項(xiàng)

  1. 在@interface @end之間聲明的成員變量如果不做特別的說明,那么其默認(rèn)是protected的
  2. 一個(gè)類繼承了另一個(gè)類,那么就擁有了父類的所有成員變量和方法,注意所有的成員變量它都擁有循捺,只是有的它不能直接訪問斩例。例如@private的

5. @property相關(guān)

1. 什么是@property

  • @property是是聲明屬性的語法
  • @property用在聲明文件中告訴編譯器聲明成員變量的的訪問器(getter/setter)方法
  • 使用@property的好處是:免去我們手工書寫getter和setter方法繁瑣的代碼

2. @property基本使用

  • 在@inteface中,@property用來自動(dòng)生成setter和getter的聲明

比如用@property int size;就可以代替下面的兩行聲明

- (int)size;   // getter

- (void)setSize:(int)size;  // setter

  • @property編寫步驟
    1. 在@inteface和@end之間寫上@property
    2. 在@property后面寫上需要生成getter/setter方法聲明的屬性名稱从橘,注意因?yàn)間etter/setter方法名稱中的屬性不需要_念赶,所以@property后的屬性也不需要_。并且@property和屬性名稱之間要用空格隔開
    3. 在@property和屬性名字之間告訴需要生成的屬性的數(shù)據(jù)類型, 注意兩邊都需要加上空格隔開

6. @synthesize相關(guān)

1. 什么是@synthesize

  • @synthesize是實(shí)現(xiàn)屬性方法的語法
  • @synthesize用在實(shí)現(xiàn)文件中告訴編譯器實(shí)現(xiàn)成員變量的的訪問器(getter/setter)方法
  • 使用@synthesize好處是:免去我們手工書寫getterr和setter方法繁瑣的代碼

2. @synthesize基本使用

  • 寫在@implementation中恰力,用來自動(dòng)生成setter和getter的實(shí)現(xiàn)

用@synthesize size; 就可以代替

- (int)size{

}

- (void)setSize:(int)size{

}

//注意:@synthesize size; 并沒有告訴setter和getter 把size賦值給誰叉谜,返回誰

而用@synthesize size= _size;就可以代替

- (int)size{

    return _size;

}

- (void)setSize:(int)size{

    _size = size;

}

  • @synthesize編寫步驟
    1. 在@implementation和@end之間寫上@synthesize
    2. 在@synthesize后面寫上和@property中一樣的屬性名稱,這樣@synthesize就會(huì)將@property生成的什么拷貝到@implementation中
    3. 由于getter/setter方法實(shí)現(xiàn)是要將傳入的形參給屬性和獲取屬性的值踩萎,所以在@synthesize的屬性后面寫上要將傳入的值賦值給誰和要返回哪個(gè)屬性的值, 并用等號(hào)連接

3. @synthesize注意點(diǎn)

  • @synthesize age = _age;
    • setter和getter實(shí)現(xiàn)中會(huì)訪問成員變量_age
    • 如果成員變量_age不存在停局,就會(huì)自動(dòng)生成一個(gè)@private的成員變量_age
  • @synthesize age;
    • setter和getter實(shí)現(xiàn)中會(huì)訪問@synthesize后同名成員變量age
    • 如果成員變量age不存在,就會(huì)自動(dòng)生成一個(gè)@private的成員變量age
  • 多個(gè)屬性可以通過一行@synthesize搞定,多個(gè)屬性之間用逗號(hào)連接

@synthesize age = _age, number = _number, name  = _name;

7. @property拓展

1. @property增強(qiáng)

  • 自Xcode4.4以后,apple對(duì)@property進(jìn)行了一個(gè)增強(qiáng)董栽,以后不用再寫@synthesize了码倦,只用一個(gè)@property就可以同時(shí)生成setter/getter方法的聲明和實(shí)現(xiàn)
  • 如果沒有告訴@property要將傳入的參數(shù)賦值給誰,默認(rèn)@property會(huì)將傳入的屬性賦值給_開頭的成員變量
用@property int size;就可以替代下面兩行聲明
- (int)size;   // getter

- (void)setSize:(int)size;  // setter

以及下面兩行實(shí)現(xiàn)
- (int)size{

    return _size;

}

- (void)setSize:(int)size{

    _size = size;

}


  • @property只會(huì)生成最簡單的getter和setter方法的聲明和實(shí)現(xiàn)锭碳,并不會(huì)對(duì)傳入的數(shù)據(jù)進(jìn)行判斷
    • 如果想對(duì)傳入的數(shù)據(jù)進(jìn)行過濾袁稽,那么我們就必須重寫getter/setter方法
    • 如果不想對(duì)傳入的數(shù)據(jù)進(jìn)行過濾,僅僅是提供一個(gè)方法給外界操作成員變量擒抛,那么就可以使用@property
    • 如果重寫了setter方法推汽,那么property就只會(huì)生成getter方法
    • 如果重寫了getter方法,那么property就只會(huì)生成setter方法
    • 如果同時(shí)重寫了getter/setter方法歧沪,那么property就不會(huì)自動(dòng)幫我們生成_開頭的成員變量(報(bào)錯(cuò))
  • 如果利用@property來生成getter/setter方法歹撒,那么我們可以不寫成員變量, 系統(tǒng)會(huì)自動(dòng)給我們生成一個(gè)_開頭的成員變量
  • 但@property自動(dòng)幫我們生成的成員變量是一個(gè)私有的成員變量, 也就是說是在.m文件中生成的, 而不是在.h文件中生成的。我們?cè)谄渌募袩o法查看該成員變量槽畔,但是可在本類中查看
@property int size; 
// 幫我們生成了一個(gè)_size的成員變量栈妆,而該成員變量_size是私有成員變量

2. @property修飾符

  • 多線程管理
    • atomic 默認(rèn)什么不寫就是atomic胁编,意思是只有一個(gè)線程訪問實(shí)例變量厢钧。效率很低
    • nonatomic 可以使用多個(gè)線程訪問實(shí)例變量。效率很快嬉橙,絕大多數(shù)情況下使用nonatomic
  • 修飾是否生成getter方法的
    • readonly 只生成getter方法早直,不生成setter方法
    • readwrite 既生成getter,又生成setter方法(默認(rèn))

@property (nonatomic, readonly) int size;
@property (nonatomic, readwrite) int color;

  • 給所生成的getter/setter方法另起一個(gè)名稱
    • getter=你定義的getter方法名稱
    • setter=你定義的setter方法名稱(注意setter方法必須要有 :)

@property (nonatomic, getter=isMarried)  BOOL  married;
// 說明市框,通常BOOL類型的屬性的getter方法要以is開頭

  • 控制setter方法的內(nèi)存管理

    • assign(默認(rèn)):不會(huì)幫我們生成setter方法內(nèi)存管理的代碼霞扬,僅僅只會(huì)生成普通的getter/setter方法,用于直接賦值枫振,不做任何內(nèi)存管理(默認(rèn)喻圃,用于非OC對(duì)象類型)。默認(rèn)什么都不寫就是assign粪滤。被assign修飾的變量不是一個(gè)對(duì)象斧拍。主要用于代表簡單的數(shù)據(jù)類型,比如int杖小、float等肆汹。
    
    @property(nonatomic, assign) int size;
    
    
    • retain:會(huì)自動(dòng)幫我們生成getter/setter方法內(nèi)存管理的代碼,在setter方法中予权,對(duì)傳入的對(duì)象進(jìn)行引用計(jì)數(shù)加1的操作昂勉。retain一般用于NSObjct類以及其子類
    
    @property (nonatomic, retain) NSNumber *count;
    // 編譯器為其生成的setter/getter方法
    
    -(NSNumber *)count {    // getter方法
        return _count;
    }
    -(void)setCount:(NSNumber *)count {    // setter
       // 1.判斷傳入的對(duì)象和當(dāng)前對(duì)象是否一樣
        if (_count != count) {
            // 2.release以前的對(duì)象
            [_count release];
            // 3.retain傳入的對(duì)象
            _count = [count retain];
        }
    }
    
    
    • copy:對(duì)原有對(duì)象進(jìn)行拷貝。常用于NSString類
    @property (nonatomic, copy) NSString *string;
    
    • strong:開啟ARC時(shí)才使用扫腺。強(qiáng)引用指針岗照,相當(dāng)于retain。默認(rèn)情況下為strong
    @property (nonatomic, strong) UIButton *btn;
    
    • weak:開啟ARC時(shí)才使用。弱引用指針攒至,相當(dāng)于assign
    @property (nonatomic, weak) UIButton *btn;
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末煞肾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嗓袱,更是在濱河造成了極大的恐慌籍救,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渠抹,死亡現(xiàn)場離奇詭異蝙昙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)梧却,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門奇颠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人放航,你說我怎么就攤上這事烈拒。” “怎么了广鳍?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵荆几,是天一觀的道長。 經(jīng)常有香客問我赊时,道長吨铸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任祖秒,我火速辦了婚禮诞吱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘竭缝。我一直安慰自己房维,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布抬纸。 她就那樣靜靜地躺著咙俩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪松却。 梳的紋絲不亂的頭發(fā)上暴浦,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音晓锻,去河邊找鬼歌焦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛砚哆,可吹牛的內(nèi)容都是我干的独撇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼纷铣!你這毒婦竟也來了卵史?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤搜立,失蹤者是張志新(化名)和其女友劉穎以躯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啄踊,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忧设,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颠通。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片址晕。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖顿锰,靈堂內(nèi)的尸體忽然破棺而出谨垃,到底是詐尸還是另有隱情,我是刑警寧澤硼控,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布刘陶,位于F島的核電站,受9級(jí)特大地震影響淀歇,放射性物質(zhì)發(fā)生泄漏易核。R本人自食惡果不足惜匈织,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一浪默、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缀匕,春花似錦纳决、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至满钟,卻和暖如春胜榔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背湃番。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工夭织, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吠撮。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓尊惰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弄屡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 1. 使用 #import 相對(duì)c的 include 是防止頭文件的重復(fù)導(dǎo)入 2. NSLog 相對(duì)于 print...
    迎風(fēng)起飛的豬閱讀 1,734評(píng)論 6 9
  • 我覺得人們都得了一種病题禀,叫做閱讀的病,一邊沾沾自喜膀捷,一邊越陷越深迈嘹。 閱讀新解:通常是人們?cè)谝庾R(shí)到自己知識(shí)貧瘠,精神...
    吳端端閱讀 631評(píng)論 6 2
  • 我不說話 不是 沒有感受 沒有感想 ...
    曼麗心語閱讀 140評(píng)論 5 3
  • 和往常一樣全庸,放學(xué)路過一個(gè)紅綠燈路口江锨。紅燈亮了。我把車停下等紅燈糕篇。卻發(fā)現(xiàn)路上亮晶晶的啄育。我對(duì)坐在后座的兒子說:“也不知...
    成長之魚閱讀 194評(píng)論 0 0