我的技術博客經常被流氓網站惡意爬取轉載。請移步原文:http://m.survivalescaperooms.com/hamhog/p/3561514.html,享受整齊的排版、有效的鏈接、正確的代碼縮進、更好的閱讀體驗。
本文翻譯自:Structuring Modern Objective-C 譯者:Ley,戴倉薯
當學習一個新技能時,比如編程語言,我們經常為了能運行,而把所有能用的都揉合在一起。再后來,我們回歸到這些習慣,并進行重新估計,采用社區中的最佳實踐并寫出更好、更有結構化的代碼。
最近,Objective-C語言收到了過多的新特性,但社區的最佳實踐還沒持續更新。這就超出了“風格”的范疇,進入了“結構”的領域。
我在最近一段時間里,審視了我自己的代碼實踐,評估了我可以在哪里做的更好,所以我想我應該和你們分享我的發現。
歡迎光臨現代Objective-C。
(以上部分感謝Ley翻譯)
唉,實例變量。從何說起呢。一句話,實例變量很糟。如果你會這樣寫:
@interface MyClass : NSObject { BOOL someVariable;}@end
別這么寫了。現在就改。
不要再聲明實例變量了,尤其別聲明在頭文件里。你應該把它們聲明為PRoperty,然后用消息機制或者“.”來訪問它們。
我之前說過為什么通過實例變量來訪問property沒有明顯的益處。事實上,通過getter/setter方法來訪問有幾個優勢。
一致性: 你不需要再去懷疑getter/setter方法有沒有副作用了,假如有的話,也肯定早就會被人注意到。
Debug: 你可以簡便地在getter/setter方法上設置斷點,而不用在運行時針對實例變量的內存地址設置watchpoint。
真的,沒有理由再去聲明實例變量、再去直接訪問這些實例變量形式的屬性了——除非是在本身覆蓋(override) getter/setter的方法里,或者在initializer/dealloc 方法里,取決于你想要代碼有多少防御性(感謝 Bryan 提供鏈接)。再除非就是習慣了,但你應該改掉這個習慣。我就改了。
更新: 我找到了官方文檔的一個鏈接,建議不要在dealloc中調用getter/setter方法。供參考。
那么只讀的屬性怎么辦呢?既然沒有setter方法,你不還是需要訪問實例變量嗎?好問題。這引出了本文的下一點。
在你public的接口中要暴露屬性或組件,使用readonly屬性是一個很好的方式。但是如果不直接訪問實例變量,怎么設置它們的值呢?答案是在 .m 文件中定義一個private的class extension。
在你的頭文件中,聲明如下:
@interface MyClass : NSObject@property (nonatomic, readonly) Type propertyName;@end
然后,在類的 implementation 文件中,在以上定義的基礎上,再定義如下:
@interface MyClass ()// Private access@property (nonatomic, strong, readwrite) Type propertyName;@end
這樣你就定義了 public 的 getter 和 private 的 setter??上部少R!現在你不需要再訪問實例變量了。
Schwa 補充了一條建議:
@ashfurrow 回復:《在頭文件中定義readonly屬性》。我還要加一條,不要在頭文件里暴露可變(mutable)對象。順便贊一下,很好的文章。
— Jonathan Wight (@schwa) January 24, 2014
定義屬性時,遵從Apple官方指南總是沒錯的。但我承認,我也不總是看得那么勤快。要記住,定義BOOL類型的屬性時,要同時手動定義一個getter方法。
@property (nonatomic, assign, getter = isSomething) BOOL something;
我經常在Objective-C新手寫的代碼里看到這種情況??傮w來說,問題在于大多數的#import語句應該只寫在 .m 文件里,而不應該寫在 .h 頭文件里。
如下面的例子。
#import "MyOtherClass.h"@interface MyClass : NSObject@property (nonatomic, strong) MyOtherClass property;@end
你可以改寫代碼如下,然后在類的 implementation 文件 yourMyClass.m 中再去 #import MyOtherClass.h 頭文件。
@class MyOtherClass;@interface MyClass : NSObject@property (nonatomic, strong) MyOtherClass property;@end
@class MyOtherClass的寫法是類的前向聲明(forward class declaration)。
這樣寫的益處良多。用類的前向聲明來代替 #import 頭文件可以提高編譯速度,可以避免循環#import,還可以讓你的頭文件更輕盈——本該如此。
(未完待續)
本文翻譯自:Structuring Modern Objective-C 譯者:Ley,戴倉薯
新聞熱點
疑難解答