這個小系列是從 "Zen and the Art of the Objective-C Craftsmanship"中 進行的摘抄,共分成6篇,大部分是講代碼風格及美化,偶爾看看也不錯。
- 原文GitHub地址:
https://github.com/objc-zen/objc-zen-book - 中文版GitHub地址:
https://github.com/oa414/objc-zen-book-cn
美化代碼
縮進使用 4 個空格,永遠不要使用 tab。(因為不同的文字處理程序對tab可能有不同的處理,在你這里是4個空格,在別的地方可能就不是了。)
-
if/else/switch/while 的大括號總是在同一行開始,在新起一行結束。
// 推薦 if (user.isHappy) { //Do something } else { //Do something else } // 不推薦 if (user.isHappy) { //Do something } else { //Do something else }
方法之間應該要有一個空行來幫助代碼看起來清晰且有組織。 方法內的空格應該用來分離功能,但是通常不同的功能應該用新的方法來定義。
-
應該總是讓冒號對齊。有一些方法簽名可能超過三個冒號,用冒號對齊可以讓代碼更具有可讀性。即使有代碼塊存在,也應該用冒號對齊方法。
// 推薦 [UIView animateWithDuration:1.0 animations:^{ // something } completion:^(BOOL finished) { // something }]; // 不推薦 [UIView animateWithDuration:1.0 animations:^{ // something } completion:^(BOOL finished) { // something }];
-
關于換行
// 推薦 self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers]; // 一行很長的代碼在第二行以一個間隔(2個空格)延續 // 不推薦 self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
-
關于括號
- 控制語句 (if-else, for, switch) 使用 Egyptian風格括號(又稱 K&R 風格,代碼段括號的開始位于一行的末尾,而不是另外起一行的風格。)
- 類的實現 和 方法的實現 不使用 Egyptian風格括號。
代碼組織
-
利用代碼塊
代碼塊如果在閉合的圓括號內的話,會返回最后語句的值。
NSURL *url = ({ NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint]; [NSURL URLWithString:urlString]; });
-
利用#pragma mark - 來分離。
- (void)dealloc { /* ... */ } - (instancetype)init { /* ... */ } #pragma mark - View Lifecycle (View 的生命周期) - (void)viewDidLoad { /* ... */ } - (void)viewWillAppear:(BOOL)animated { /* ... */ } - (void)didReceiveMemoryWarning { /* ... */ } #pragma mark - Custom Accessors (自定義訪問器) - (void)setCustomProperty:(id)value { /* ... */ } - (id)customProperty { /* ... */ } #pragma mark - IBActions - (IBAction)submitData:(id)sender { /* ... */ } #pragma mark - Public - (void)publicMethod { /* ... */ } #pragma mark - Private - (void)zoc_privateMethod { /* ... */ } #pragma mark - UITableViewDataSource - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ } #pragma mark - ZOCSuperclass // ... 重載來自 ZOCSuperclass 的方法 #pragma mark - NSObject - (NSString *)description { /* ... */ }
-
忽略沒用使用變量的編譯警告
- (NSInteger)giveMeFive { NSString *foo; #pragma unused (foo) // 注意,要標記到變量之后 return 5; }
-
明確編譯器警告和錯誤
- (NSInteger)divide:(NSInteger)dividend by:(NSInteger)divisor { #error Whoa, buddy, you need to check for zero here! return (dividend / divisor); } - (float)divide:(float)dividend by:(float)divisor { #warning Dude, don't compare floating point numbers like this! if (divisor != 0.0) { return (dividend / divisor); } else { return NAN; } }
-
字符串文檔
短文檔適用于單行的文件,包括注釋斜杠。它適合簡短的函數,特別是(但不僅僅是)非 public 的 API。
// Return a user-readable form of a Frobnozz, html-escaped.
如果描述超過一行,應改用長字符串文檔:
以/**開始
換行寫一句總結的話,以?或者!或者.結尾。
空一行
在與第一行對齊的位置開始寫剩下的注釋
最后用*/結束。
/** This comment serves to demonstrate the format of a docstring. Note that the summary line is always at most one line long, and after the opening block comment, and each line of text is preceded by a single space. */
一個函數必須有一個字符串文檔,除非它符合下面的所有條件:
非公開
很短
顯而易見
字符串文檔應該描述函數的調用符號和語義,而不是它如何實現。
-
關于注釋
頭文檔
一個類的文檔應該只在 .h 文件里用 Doxygen/AppleDoc 的語法書寫。 方法和屬性都應該提供文檔。
/** * Designated initializer. * * @param store The store for CRUD operations. * @param searchService The search service used to query the store. * * @return A ZOCCRUDOperationsStore object. */ - (instancetype)initWithOperationsStore:(id<ZOCGenericStoreProtocol>)store searchService:(id<ZOCGenericSearchServiceProtocol>)searchService;
也就是說,當你定義一個類并且對外提供接口,那么需要在頭文件中對這個類進行說明,并且對每一個屬性/方法都要有明確的說明(使用上面提到的方式,用Doxygen/AppleDoc語法來書寫注釋。包括方法的參數,返回值等。)。而在實現文件中,如果一個方法/屬性是簡單,顯而易見并且非公開的,那么可以不寫注釋,前提是保證讓人一看就懂。
所有文章
【objc-zen-book】1.條件語句&Case語句的注意
【objc-zen-book】2.命名
【objc-zen-book】3.類
【objc-zen-book】4.Category & NSNotification
【objc-zen-book】5.美化代碼 & 代碼組織
【objc-zen-book】6.Block & self的循環引用
?