interface和setter,getter

前篇說到我們通過ObjC的Category特性給日常工作增加便捷的實現(xiàn)活尊,這一篇則要從語言設(shè)計角度隶校,跟大家分享一些思考。

不要忽視interface

ObjC的@interface設(shè)計蛹锰,跟Java和C#真的很像深胳,但又略有不同,相比之下Java和C#則像是一個模子刻出來的铜犬。ObjC的特點十分明顯舞终,首先是一般不用寫@private@public來區(qū)分私有變量轻庆,大部分ObjC開發(fā)者甚至都不知道還有這兩個關(guān)鍵字,其實Cocoa源代碼中也基本沒有使用過這種設(shè)計敛劝,即使ObjC是支持的余爆。

在@interface 中使用 @private和@public

@interface Student : NSObject
{
    @private
    NSString* _name;
    @public
    NSNumber* _age;
    int _height;
}
@end

如上代碼中,Student有一個私有變量_name夸盟,和兩個共有變量_age蛾方、_height,但在@interface中聲明變量满俗,一定不是Cocoa設(shè)計者的初衷转捕,這里有兩個方面的考慮。

其一唆垃,把內(nèi)部變量直接暴露在外五芝,會降低整個框架的穩(wěn)定性,因為增加不同模塊之間的耦合辕万,降低了每個類的內(nèi)聚性枢步。
其二,內(nèi)部變量的變量名渐尿,很容易跟局部變量變量名產(chǎn)生沖突醉途。上例中我給每一個變量名前加了下劃線,就是為了防止這個問題發(fā)生砖茸。

所以縱觀Cocoa框架的頭文件設(shè)計隘擎,基本沒有這樣的代碼,因為設(shè)計者提供了更好的實現(xiàn)方式凉夯,就是大家用的更多的@property關(guān)鍵字货葬。

如果用@property聲明上面的類,大家都很熟悉

@interface Student : NSObject

@property (nonatomic, strong) NSString* name;
@property (nonatomic, strong) NSNumber* age;
@property (nonatomic, assign) NSInteger height;

@end

@property這個設(shè)計真的很有意思劲够,首先我們不再區(qū)分私有公有屬性震桶,因為只要寫在.h里面的@property,我們都默認(rèn)是共有的征绎,私有的@property可以寫在.m文件里蹲姐。

其次,配合寫在@implementation里面的@synthesize關(guān)鍵字人柿,可以自動生成setter和getter方法柴墩,而現(xiàn)在@synthesize關(guān)鍵字都可以省略,除了個別情況有修改內(nèi)部變量名稱的需求凫岖。

@implementation Student
@synthesize name = _name;
@synthesize age = __age;
@end

上面的@synthesize拐邪,第一個是可以省略的,在不寫的情況下隘截,編譯預(yù)處理會自動給添加@synthesize代碼扎阶,所以即使沒有合成(synthesize)height屬性汹胃,我們依然實現(xiàn)了它的setter和getter方法

//這兩個方法可以重寫

- (void)setHeight:(NSInteger)height
{
    _height = height;
}

- (NSInteger)height
{
    return _height;
}

在setter和getter方法均重寫的情況下,@synthesize需要手動添加东臀。

@synthesize height = _height;

為什么要使用 setter 和 getter

settergetter的設(shè)計的確值得琢磨着饥,我們主要從以下幾點分析:

setter 和 getter 包裝了內(nèi)部變量,整個類對外可以只暴露接口惰赋,增強(qiáng)類的內(nèi)聚性宰掉。

例如上例中的內(nèi)部變量_name,外部類是無法操作的赁濒,只能通過set和get接口來發(fā)消息:

Student* s = [[Student alloc] init];

[s setName:@"Tom"];
[s name];

通過實現(xiàn) getter方法轨奄,可以避開初始化變量的時機(jī)問題

這也是很實用的一個點,因為ObjC的消息設(shè)計機(jī)制拒炎,導(dǎo)致ObjC很難在初始化(init)方法中傳入過多參數(shù)(題外話挪拟,我給ObjC擴(kuò)展過依賴注入,詳見iOS實現(xiàn)依賴注入)击你。因此新實例的默認(rèn)屬性玉组,放在什么位置實現(xiàn)合適,是大家一定遇到過的問題丁侄。

例如最常見的UIViewController惯雳,代碼初始化走init方法,而通過storyboard實力化則走initWithCoder方法鸿摇,一些容器屬性石景,通過getter方法初始化,則可避免第一次調(diào)用尚未初始化造成的問題拙吉。

早期的Cocoa在如果給nil發(fā)消息潮孽,是會引起異常的,現(xiàn)在的版本給沒有alloc的對象發(fā)消息不再拋異常庐镐,以至于某些時候?qū)傩詻]有初始化造成的問題變得更隱蔽恩商,然而重寫getter方法可以有效避免這個問題变逃,例如:

//班級類
@interface XXClass : NSObject
@property (nonatomic, strong) NSMutableArray* students; //學(xué)生
@end

@implementation

//實現(xiàn)getter方法必逆,在內(nèi)部變量_students沒初始化的情況下將其初始化
- (NSMutableArray *)students
{
    if (!_students) {
        _students = [NSMutableArray array];
    }
    return _students;
}

@end

如此一來,無論在任何時候揽乱,第一次發(fā)送[self students]消息的時候名眉,內(nèi)部變量_students都會初始化。

在這里要另外注明一點凰棉,在類的內(nèi)部损拢,不要在setter和getter方法外,直接使用內(nèi)部變量撒犀,遵守這一條會收益很多福压。

setter 和 getter 可以單獨使用掏秩,也可以脫離內(nèi)部變量使用

這里要說的就是@property的靈活性了,大家知道@property擁有一系列的修飾詞荆姆,除了常用的nonatomic(非原子化蒙幻,線程安全)strong(強(qiáng)引用類型)胆筒,weak(弱引用類型)邮破,assign(賦值,用于非對象屬性)以外仆救,還有readonly(只讀)readwrite(可讀寫)兩個影響setter和getter方法的屬性抒和,readonly修飾的屬性,只有g(shù)etter方法而沒有setter方法彤蔽。

readwrite則是一個看起來可有可無的修飾詞摧莽,因為默認(rèn)就是可讀寫。然而它其實有個專門設(shè)計的用法铆惑,就是在.h中的interface中被readonly修飾的屬性范嘱,可以在這個類的其他類別(category)或者匿名類別中重新聲明這個屬性時,修改其讀寫限制员魏,例如

//班級類
@interface XXClass : NSObject
@property (nonatomic, strong, readonly) NSMutableArray* students; //學(xué)生
@end
//匿名類別
@interface XXClass()
@property (nonatomic, strong, readwrite) NSMutableArray* students;
@end

這樣一來丑蛤,因為匿名類別一般寫在.m文件里(基本沒見過寫在.h文件里的),所以外部是不能調(diào)用students屬性的setter方法撕阎,而XXClass類內(nèi)部則可以使用受裹。

還有一種常見情況是用setter和getter來模擬屬性(@property),例如:

//班級類
@interface XXClass : NSObject
@property (nonatomic, strong, readonly) NSMutableArray* students; //學(xué)生
@property (nonatomic, assign, readonly) NSUInteger studentsCount; //學(xué)生數(shù)量
@end
- (NSUInteger)studentsCount
{
    return self.students.count;
}

這里的studentsCount是沒有內(nèi)部變量的虏束,通過getter方法偽造成屬性接口棉饶。

小結(jié)

這一篇是ObjC的接口設(shè)計模式的一部分,寫的比較詳細(xì)是幫助新手入門镇匀,給有經(jīng)驗的朋友帶來一些思考照藻,并引出接下來的內(nèi)容。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汗侵,一起剝皮案震驚了整個濱河市幸缕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晰韵,老刑警劉巖发乔,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異雪猪,居然都是意外死亡栏尚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門只恨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來译仗,“玉大人抬虽,你說我怎么就攤上這事∽菥” “怎么了斥赋?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長产艾。 經(jīng)常有香客問我疤剑,道長,這世上最難降的妖魔是什么闷堡? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任隘膘,我火速辦了婚禮,結(jié)果婚禮上杠览,老公的妹妹穿的比我還像新娘弯菊。我一直安慰自己,他們只是感情好踱阿,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布管钳。 她就那樣靜靜地躺著,像睡著了一般软舌。 火紅的嫁衣襯著肌膚如雪才漆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天佛点,我揣著相機(jī)與錄音醇滥,去河邊找鬼。 笑死超营,一個胖子當(dāng)著我的面吹牛鸳玩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播演闭,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼不跟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了米碰?” 一聲冷哼從身側(cè)響起窝革,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎见间,沒想到半個月后聊闯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體工猜,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡米诉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了篷帅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片史侣。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡拴泌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惊橱,到底是詐尸還是另有隱情蚪腐,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布税朴,位于F島的核電站回季,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏正林。R本人自食惡果不足惜泡一,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望觅廓。 院中可真熱鬧鼻忠,春花似錦、人聲如沸杈绸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞳脓。三九已至塑娇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間劫侧,已是汗流浹背钝吮。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留板辽,地道東北人奇瘦。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像劲弦,于是被迫代替她去往敵國和親耳标。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

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

  • 中國美業(yè)百家名師 2016美甲世界杯裁判員 美業(yè)分會技術(shù)美甲導(dǎo)師 廣東省人力資源局高級美甲師 深圳市職業(yè)培訓(xùn)學(xué)校職...
    美業(yè)紀(jì)錄閱讀 481評論 0 0
  • 一直以來邑跪,我對自己的睡眠都是特別的滿意次坡,因為我是屬于躺下就能睡著類型的,一般情況下都能在鬧鐘響前幾分鐘醒來画畅。不過起...
    小粉豬閱讀 604評論 1 1
  • 林庚——春天的心如草的荒蕪 隨便的踏出門去 美麗的東西到處可以揀起來 少女的心情是不能說的 天上的雨點常是落下 而...
    遇了個黑天鵝閱讀 381評論 0 0