鍍金池/ 教程/ iOS/ 留白和格式
Cocoa 和 Objective-C 特性
留白和格式
命名
注釋
Cocoa 模式

留白和格式

空格 vs. 制表符

Tip
只使用空格,且一次縮進(jìn)兩個(gè)空格。

我們使用空格縮進(jìn)。不要在代碼中使用制表符。你應(yīng)該將編輯器設(shè)置成自動(dòng)將制表符替換成空格。

行寬

盡量讓你的代碼保持在 80 列之內(nèi)。

我們深知 Objective-C 是一門繁冗的語(yǔ)言,在某些情況下略超 80 列可能有助于提高可讀性,但這也只能是特例而已,不能成為開脫。

如果閱讀代碼的人認(rèn)為把把某行行寬保持在 80 列仍然有不失可讀性,你應(yīng)該按他們說(shuō)的去做。

我們意識(shí)到這條規(guī)則是有爭(zhēng)議的,但很多已經(jīng)存在的代碼堅(jiān)持了本規(guī)則,我們覺(jué)得保證一致性更重要。

通過(guò)設(shè)置 -Xcode > Preferences > Text Editing > Show page guide-,來(lái)使越界更容易被發(fā)現(xiàn)。

方法聲明和定義

Tip
/ + 和返回類型之間須使用一個(gè)空格,參數(shù)列表中只有參數(shù)之間可以有空格。

方法應(yīng)該像這樣:

    - (void)doSomethingWithString:(NSString -)theString {
      ...
    }

星號(hào)前的空格是可選的。當(dāng)寫新的代碼時(shí),要與先前代碼保持一致。

如果一行有非常多的參數(shù),更好的方式是將每個(gè)參數(shù)單獨(dú)拆成一行。如果使用多行,將每個(gè)參數(shù)前的冒號(hào)對(duì)齊。

    - (void)doSomethingWith:(GTMFoo -)theFoo
                       rect:(NSRect)theRect
                   interval:(float)theInterval {
      ...
    }

當(dāng)?shù)谝粋€(gè)關(guān)鍵字比其它的短時(shí),保證下一行至少有 4 個(gè)空格的縮進(jìn)。這樣可以使關(guān)鍵字垂直對(duì)齊,而不是使用冒號(hào)對(duì)齊:

    - (void)short:(GTMFoo -)theFoo
        longKeyword:(NSRect)theRect
        evenLongerKeyword:(float)theInterval {
      ...
    }

方法調(diào)用

Tip
方法調(diào)用應(yīng)盡量保持與方法聲明的格式一致。當(dāng)格式的風(fēng)格有多種選擇時(shí),新的代碼要與已有代碼保持一致。

調(diào)用時(shí)所有參數(shù)應(yīng)該在同一行:

    [myObject doFooWith:arg1 name:arg2 error:arg3];

或者每行一個(gè)參數(shù),以冒號(hào)對(duì)齊:

    [myObject doFooWith:arg1
                   name:arg2
                  error:arg3];

不要使用下面的縮進(jìn)風(fēng)格:

    [myObject doFooWith:arg1 name:arg2  // some lines with >1 arg
                  error:arg3];

    [myObject doFooWith:arg1
                   name:arg2 error:arg3];

    [myObject doFooWith:arg1
              name:arg2  // aligning keywords instead of colons
              error:arg3];

方法定義與方法聲明一樣,當(dāng)關(guān)鍵字的長(zhǎng)度不足以以冒號(hào)對(duì)齊時(shí),下一行都要以四個(gè)空格進(jìn)行縮進(jìn)。

    [myObj short:arg1
        longKeyword:arg2
        evenLongerKeyword:arg3];

@public@private

Tip
    ``@public`` 和 ``@private`` 訪問(wèn)修飾符應(yīng)該以一個(gè)空格縮進(jìn)。

與 C++ 中的 public, private 以及 protected 非常相似。

    @interface MyClass : NSObject {
     @public
      ...
     @private
      ...
    }
    @end

異常

Tip
    每個(gè) ``@`` 標(biāo)簽應(yīng)該有獨(dú)立的一行,在 ``@`` 與 ``{}`` 之間需要有一個(gè)空格, ``@catch`` 與被捕捉到的異常對(duì)象的聲明之間也要有一個(gè)空格。

如果你決定使用 Objective-C 的異常,那么就按下面的格式。不過(guò)你最好先看看 :ref:避免拋出異常 <avoid-throwing-exceptions> 了解下為什么不要使用異常。

    @try {
      foo();
    }
    @catch (NSException -ex) {
      bar(ex);
    }
    @finally {
      baz();
    }

協(xié)議名

Tip
    類型標(biāo)識(shí)符和尖括號(hào)內(nèi)的協(xié)議名之間,不能有任何空格。

這條規(guī)則適用于類聲明、實(shí)例變量以及方法聲明。例如:

    @interface MyProtocoledClass : NSObject<NSWindowDelegate> {
     @private
      id<MyFancyDelegate> delegate_;
    }
    - (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
    @end

塊(閉包)

Tip
    塊(block)適合用在 target/selector 模式下創(chuàng)建回調(diào)方法時(shí),因?yàn)樗勾a更易讀。塊中的代碼應(yīng)該縮進(jìn) 4 個(gè)空格。

取決于塊的長(zhǎng)度,下列都是合理的風(fēng)格準(zhǔn)則:

  • 如果一行可以寫完塊,則沒(méi)必要換行。
  • 如果不得不換行,關(guān)括號(hào)應(yīng)與塊聲明的第一個(gè)字符對(duì)齊。
  • 塊內(nèi)的代碼須按 4 空格縮進(jìn)。
  • 如果塊太長(zhǎng),比如超過(guò) 20 行,建議把它定義成一個(gè)局部變量,然后再使用該變量。
  • 如果塊不帶參數(shù),^{ 之間無(wú)須空格。如果帶有參數(shù),^( 之間無(wú)須空格,但 ) { 之間須有一個(gè)空格。
  • 塊內(nèi)允許按兩個(gè)空格縮進(jìn),但前提是和項(xiàng)目的其它代碼保持一致的縮進(jìn)風(fēng)格。
    // 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) {
          // ...
        }
    });

    // 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) = ^{
        // ...
    };
    [operationQueue_ addOperationWithBlock:largeBlock];
上一篇:注釋下一篇:Cocoa 和 Objective-C 特性