Cocoa代碼風格指南之排版規(guī)范(二)

本文基于 Google 的代碼風格指南中關于排版規(guī)范的部分的總結,其中部門內容具有主觀性。本文所有代碼的排版均為建議的格式,如有文字上疏漏的地方,可以參考任何一段代碼。首先通過一段代碼來了解基本的排版格式。

  • [Apple]:Apple 明確給出建議
  • [Google]:Google 明確給出建議
  • [General]:通用做法(主觀)
#import <Foundation/Foundation.h>

@interface Foo : NSObject

+ (instancetype)fooWithBar:(NSString *)bar;

- (instancetype)initWithBar:(NSString *)bar;

- (NSString *)bar;
- (void)setBar:(NSString *)bar;

- (BOOL)doWorkWithBlah:(NSString *)blah;

@end
#import "Foo.h"

@implementation Foo {
    NSString *bar;
    NSString *bam;
}

+ (id)fooWithBar:(NSString *)bar {
    return [[self alloc] initWithBar:bar];
}

- (id)init {
    return [self initWithBar:nil];
}

- (id)initWithBar:(NSString *)bar {
    self = [super init]
    if (self) {
        _bar = [bar copy];
        _bam = [[NSString alloc] initWithFormat:@"hi %d", 3];
    }
    return self;
}

- (NSString *)bar {
    return _bar;
}

- (void)setBar:(NSString *)bar {
    _bar = [bar copy];
}

- (BOOL)doWorkWithBlah:(NSString *)blah {
    return NO;
}

@end

上述代碼中的所有換行、空格、縮進都為建議的格式。下邊將進行更加詳細的描述。

空格和制表符 [Google][General]

Google 建議使用2個空格來進行縮進,并且將編輯器設置成自動將制表符替換成空格。但這不符合大多數(shù) Objective-C 程序員的習慣。所以還是建議所有的縮進都使用單個制表符。

行寬 [Google][General]

盡量讓你的代碼保持在 80 列之內。Objective-C 是一門繁冗的語言,在某些情況下略超 80 列可能有助于提高可讀性,但這也只能是特例而已,不能成為開脫。如果閱讀代碼的人認為把把某行行寬保持在 80 列仍然有不失可讀性,你應該按他們說的去做。這條規(guī)則是有爭議的,但很多已經存在的代碼堅持了本規(guī)則,所以 Google 覺得保證一致性更重要。通過設置 Xcode > Preferences > Text Editing > Show page guide,來使越界更容易被發(fā)現(xiàn)。這條規(guī)則對我個人有很強的約束,但很多代碼難以實現(xiàn)80列,所以在這里還有很多值得探索的寫法。

屬性 [General]

@property (nonatomic, strong) NSString *string;
@property (nonatomic, weak) id<XXDelegate> delegate;
  • property 后留空格
  • nonatomic 放在修飾符第一位
  • 內存管理修飾符放在第二位
  • 修飾符中間在“,”后留空格
  • 修飾符“()”后留空格
  • 所有變量的類名后留空格
  • 類型標識符和尖括號內的協(xié)議名之間不能有任何空格

方法 [General]

- (void)doSomethingWith:(GTMFoo *)theFoo
                   rect:(NSRect)theRect
               interval:(float)theInterval {
    // TODO
}
- (void)short:(GTMFoo *)theFoo
    longKeyword:(NSRect)theRect
    evenLongerKeyword:(float)theInterval {
    // TODO
}
  • 方法返回值前留空格
  • 方法返回值后不留空格
  • 左括號和方法名在同行并有空格隔開
  • 多個參數(shù)的方法換行并以冒號對齊
  • 換行后如有某行過長導致冒號無法對齊則整體縮進一個制表符
  • 方法在聲明、實現(xiàn)、調用時均上述規(guī)則

Block [Google][General]

// The entire block fits on one line.
[operation setCompletionBlock:^{ [self onOperationDone]; }];

// The block can be put on a new line, indented four spaces, with the
// closing brace aligned with the first character of the line on which
// block was declared.
[operation setCompletionBlock:^{
    [self.delegate newDataAvailable];
}];

// Using a block with a C API follows the same alignment and spacing
// rules as with Objective-C.
dispatch_async(fileIOQueue_, ^{
    NSString* path = [self sessionFilePath];
    if (path) {
        // TODO
    }
});

// An example where the parameter wraps and the block declaration fits
// on the same line. Note the spacing of |^(SessionWindow *window) {|
// compared to |^{| above.
[[SessionService sharedService]
    loadWindowWithCompletionBlock:^(SessionWindow *window) {
        if (window) {
            [self windowDidLoad:window];
        } else {
            [self errorLoadingWindow];
        }
    }];

// An example where the parameter wraps and the block declaration does
// not fit on the same line as the name.
[[SessionService sharedService]
    loadWindowWithCompletionBlock:
        ^(SessionWindow *window) {
            if (window) {
                [self windowDidLoad:window];
            } else {
                [self errorLoadingWindow];
            }
        }];

// Large blocks can be declared out-of-line.
void (^largeBlock)(void) = ^{
    // TODO
};
[operationQueue_ addOperationWithBlock:largeBlock];
  1. 如果一行可以寫完塊,則沒必要換行。
  2. 如果不得不換行,關括號應與塊聲明的第一個字符對齊。
  3. 塊內的代碼須按 4 空格縮進。
  4. 如果塊太長,比如超過 20 行,建議把它定義成一個局部變量,然后再使用該變量。
  5. 如果塊不帶參數(shù),^{ 之間無須空格。如果帶有參數(shù),^( 之間無須空格,但 ) { 之間須有一個空格。
  6. 塊內允許按兩個空格縮進,但前提是和項目的其它代碼保持一致的縮進風格。
  • 如果重載了 NSObject 類的方法,強烈建議把它們放在 @implementation 內的起始處,這也是常見的操作方法。通常適用(但不局限)于 init...,copyWithZone:,以及 dealloc 方法。所有 init... 方法應該放在一起,copyWithZone: 緊隨其后,最后才是 dealloc 方法。 [Google][General]

  • 指定初始化方法使用 NS_DESIGNATED_INITIALIZER 標示。 [General]

  • 寫子類時如果需要 init… 方法,記得重載父類的指定構造函數(shù)。 [Google][General]

// UIView
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // TODO
    }
    return self;
}

博客:xuyafei.cn
簡書:jianshu.com/users/2555924d8c6e
微博:weibo.com/xuyafei86
Github:github.com/xiaofei86

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • iOS編程規(guī)范0規(guī)范 0.1前言 為??高產品代碼質量,指導廣大軟件開發(fā)人員編寫出簡潔、可維護、可靠、可 測試、高效...
    iOS行者閱讀 4,625評論 21 35
  • 推薦文章:禪與 Objective-C 編程藝 前言 為??高產品代碼質量,指導廣大軟件開發(fā)人員編寫出簡潔、可維護、...
    MurtoTien閱讀 2,947評論 0 1
  • Cocoa代碼風格指南之命名規(guī)范(一) Cocoa代碼風格指南之排版規(guī)范(二) Cocoa代碼風格指南之注釋規(guī)范(...
    xuyafei86閱讀 3,534評論 0 8
  • 一個統(tǒng)一的編程風格不但能夠增強代碼可讀性,也可以避免許多低級問題。一個嚴格遵從編碼規(guī)范的團隊,代碼無論出自多少人之...
    七弦桐語閱讀 692評論 0 2
  • 11月的最后一天,起的不算早今天要去報道了,但是有些沒自信即使需要面對巨額信用卡賬單,我相信我能搞定人生就是這樣,...
    小白和小黑閱讀 335評論 0 0

友情鏈接更多精彩內容