編寫高質量iOS與OS X代碼的52個有效方法(二)

編寫高質量iOS與OS X代碼的52個有效方法(一)
編寫高質量iOS與OS X代碼的52個有效方法(三)

對象劫灶、消息筛严、運行期

6、理解“屬性”這一概念

“屬性”是OC的一項特性句喷,用于封裝對象中的數(shù)據(jù)。OC對象通常會把其所需要的數(shù)據(jù)保存為各種實例對象俱恶。實例對象一般通過“存取方法”來訪問帖族。其中,“獲取方法(getter)”用于讀取變量值逊抡,而“設置方法(setter)”用于寫入變量值。

屬性特質

@property (nonatomic, readwrite, copy) NSString *firstName;

屬性可以擁有的特質分為四類:

原子性

在默認情況下零酪,由比編譯器合成的方法會通過鎖定機制確保其原子性冒嫡。如果屬性具備nonatomic特質,則不使用同步鎖四苇。請注意孝凌,盡管沒有名為“atomic”的特質(如果某屬性不具備nonatomic特質,那他就是“原子的”(atomic))月腋,但是仍然可以在屬性特質中寫明這一點蟀架,編譯器不會報錯。若是自己定義存取方法榆骚,那么久應該遵從與屬性特質享福的原子性片拍。

讀/寫權限
  • 具備readwrite特質的屬性擁有“獲取方法(getter)與設置方法(setter)”。若該屬性由@synthesize實現(xiàn)妓肢,則編譯器會自動生成這兩個方法捌省。
  • 具備readonly特質的屬性僅擁有獲取方法,只有當該屬性由@synthesize實現(xiàn)時碉钠,編譯器才會為其合成獲取方法所禀。你可以用此特質把某個屬性對外公開為只讀屬性,然后再“class-aontonuation”分類中將其重新定義為讀寫屬性放钦。

內(nèi)存管理語義

屬性用于封裝數(shù)據(jù),而數(shù)據(jù)則要有“具體的所有權語義”恭金。

  • assign “設置方法”只會執(zhí)行針對“純量類型”(例如:CGFloat或NSInteger等)的簡單賦值操作操禀。
  • strong 此特質表明該屬性定義了一種“擁有關系”。為這種屬性設置新值時横腿,設置方法會先保留新值颓屑,并釋放舊值,然后再將新值設置上去耿焊。
  • weak 次特質表明該屬性定義了一種“非擁有關系”揪惦。為這種屬性設置新值時,設置方法既不保留新值罗侯,也不釋放舊值器腋。此特質同assign類似,然而再屬性所指的對象遭到摧毀時,屬性值也會清空(nil out)纫塌。
  • unsafe_unretained 此特質的語義和assign相同诊县,但是他適用于“對象類型”,該特質表達一種“非擁有關系”(“不保留”措左, unretained)依痊,當目標對象遭到摧毀時,屬性值不會自動清空(“不安全”怎披, unsafe)胸嘁,這一點與weak有區(qū)別。
  • copy 此特質所表達的所屬關系與strong類似凉逛。然而設置方法并不保留新值性宏,而是將其“拷貝(copy)”。當屬性類型為NSString時鱼炒,經(jīng)常用此特質來保護其封裝性衔沼,因為傳遞給設置的新值有可能指向一個NSMutableString類的實例。所以要“拷貝”一個”不可變“的字符串昔瞧,確保對象中的字符串值不會無意間變動指蚁。
方法名
  • getter=<name>
@peroperty (nonatomic, getter=isOn) BOOL on;
  • setter=<name>

要點

  • 可以用@property語法來定義對象中所封裝的數(shù)據(jù)。
  • 通過“特質”來指定存儲數(shù)據(jù)所需的正確語義自晰。
  • 在設置屬性所對應的實例變量時凝化,一定要遵守從該屬性所聲明的語義。
  • 開發(fā)iOS程序時應該使用nonatomic屬性酬荞,因為atomic屬性會嚴重影響性能搓劫。

7、在對象內(nèi)部盡量直接訪問實例變量

@interface Eoperson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
- (NSString*)fullName;
- (void)setFullName:(NSString*)fullName;
@end
//fullName與setFullName這兩個方法可以這樣實現(xiàn)
- (NSString*)fullName {
  return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
- (void)setFullName:(NSString*)fullName {
  NSSArray *components = [fullName componnentsSeparatedByString:@" "];
  self.firstName = [components objectAtIndex: 0];
  self.lastName = [components objectAtIndex: 1];
}

在fullName的獲取方法與設置方法中,我們使用"點語法"混巧,通過存取方法來訪問相關的實例變量∏瓜颍現(xiàn)在假設重寫這兩個方法,不經(jīng)由存取方法,而是直接訪問實例變量

- (NSString*)fullName {
  return [NSString stringWithFormat:@"%@ %@", _firstName, _lastName];
}
- (void)setFullName:(NSString*)fullName {
  NSSArray *components = [fullName componnentsSeparatedByString:@" "];
  _firstName = [components objectAtIndex: 0];
  _lastName = [components objectAtIndex: 1];
}
這兩種方法的區(qū)別
  • 由于不經(jīng)過Objective-C的“方法派對”,所以直接訪問實例變量的速度當然比較快咧党。在這種情況下秘蛔,編譯器所生成的代碼塊會直接訪問保存對象實例變量的那塊內(nèi)存。
  • 直接訪問實例變量傍衡,不會調用其“設置方法”深员,這就繞過了對相關屬性定義的“內(nèi)存管理語義”。比方說蛙埂,如果在ARC下直接訪問一個聲明為copy的屬性倦畅,那么并不會拷貝該屬性,只會保留新值并釋放新值绣的。
  • 如果直接訪問實例變量叠赐,不會觸發(fā)“鍵值觀察(KVO)”欲账。這樣做是否會產(chǎn)生新的問題,還取決具體的對象行為燎悍。
  • 通過屬性來訪問有助于排查與之相關的錯誤敬惦,因為可以給“獲取方法”和“設置方法”添加斷點,監(jiān)控該屬性的調用者及訪問時機谈山。
要點
  • 在對象讀取內(nèi)部數(shù)據(jù)時俄删,應該直接用過實例變量來讀,而寫入數(shù)據(jù)的時候奏路,則通過屬性來寫畴椰。
  • 在初始化和dealloc方法中,總是應該直接通過實例變量來讀寫數(shù)據(jù)鸽粉。
  • 有時會用懶惰性初始化技術配置某分數(shù)據(jù)斜脂,這種情況下,需要通過屬性來讀取數(shù)據(jù)触机。

8帚戳、理解“對象等同性”這一概念

特定類所具有等同性判定方法

例如:“isEqualToArray:”“isEqualToDictionary”

等同性判定的執(zhí)行深度

創(chuàng)建等同性判定方法時,需要決定是根據(jù)整個對象來判斷等同性儡首,換是根據(jù)其中幾個字段來判斷片任。NSA仍然有的檢測方式為先看兩個數(shù)組包含的對象個數(shù)是否相同,若相同蔬胯,則在兩個對應位置的兩個對象身上調用“isEqual:”方法对供。如果對象位置身上均相等,那么這兩個數(shù)組就想等氛濒,這就叫做“深度等同性判定”产场。不過有時候無須降所有數(shù)據(jù)逐個比較,只根據(jù)其中部分數(shù)據(jù)即可判定二者是否相同舞竿。
假如京景,一個Persion類是根據(jù)數(shù)據(jù)庫里的數(shù)據(jù)創(chuàng)建出來的,那么其中就可能會含有另外一個屬性骗奖,此屬性是“唯一標識符”醋粟,那么我們只需要檢測兩個對象中的標識符是否相同就能判定兩個對象是否相等。

容器中可變類的等同性

容器中放入可變對象的時候重归,就不應在改變其哈希碼了。

要點
  • 若想檢測對象的等同性厦凤,請?zhí)峁癷sEqual:”與hash方法鼻吮。
  • 相同的對象必須具有相同的哈希碼,但是兩個哈希碼相同的對象卻未必相同较鼓。
  • 不要盲目的諸葛檢測每個屬性椎木,而是應該依照具體需求來制定監(jiān)測方案违柏。
  • 編寫hash方法時,應該使用計算速度快而哈希碼碰撞幾率低的算法香椎。
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漱竖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子畜伐,更是在濱河造成了極大的恐慌馍惹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玛界,死亡現(xiàn)場離奇詭異万矾,居然都是意外死亡,警方通過查閱死者的電腦和手機慎框,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門良狈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笨枯,你說我怎么就攤上這事薪丁。” “怎么了馅精?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵严嗜,是天一觀的道長。 經(jīng)常有香客問我硫嘶,道長阻问,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任沦疾,我火速辦了婚禮称近,結果婚禮上,老公的妹妹穿的比我還像新娘哮塞。我一直安慰自己刨秆,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布忆畅。 她就那樣靜靜地躺著衡未,像睡著了一般。 火紅的嫁衣襯著肌膚如雪家凯。 梳的紋絲不亂的頭發(fā)上缓醋,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音绊诲,去河邊找鬼送粱。 笑死,一個胖子當著我的面吹牛掂之,可吹牛的內(nèi)容都是我干的抗俄。 我是一名探鬼主播脆丁,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼动雹!你這毒婦竟也來了槽卫?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤胰蝠,失蹤者是張志新(化名)和其女友劉穎歼培,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姊氓,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡丐怯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翔横。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片读跷。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖禾唁,靈堂內(nèi)的尸體忽然破棺而出效览,到底是詐尸還是另有隱情,我是刑警寧澤荡短,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布丐枉,位于F島的核電站,受9級特大地震影響掘托,放射性物質發(fā)生泄漏瘦锹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一闪盔、第九天 我趴在偏房一處隱蔽的房頂上張望弯院。 院中可真熱鬧,春花似錦泪掀、人聲如沸听绳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椅挣。三九已至,卻和暖如春塔拳,著一層夾襖步出監(jiān)牢的瞬間鼠证,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工靠抑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留名惩,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓孕荠,卻偏偏與公主長得像娩鹉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子稚伍,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353