• 留白和格式
    • 空格 vs. 制表符
    • 行宽
    • 方法声明和定义
    • 方法调用
    • @public 和 @private
    • 异常
    • 协议名
    • 块(闭包)

    留白和格式

    空格 vs. 制表符

    Tip

    只使用空格,且一次缩进两个空格。

    我们使用空格缩进。不要在代码中使用制表符。你应该将编辑器设置成自动将制表符替换成空格。

    行宽

    尽量让你的代码保持在 80 列之内。

    我们深知 Objective-C 是一门繁冗的语言,在某些情况下略超 80 列可能有助于提高可读性,但这也只能是特例而已,不能成为开脱。

    如果阅读代码的人认为把把某行行宽保持在 80 列仍然有不失可读性,你应该按他们说的去做。

    我们意识到这条规则是有争议的,但很多已经存在的代码坚持了本规则,我们觉得保证一致性更重要。

    通过设置 Xcode > Preferences > Text Editing > Show page guide,来使越界更容易被发现。

    方法声明和定义

    Tip

    • / + 和返回类型之间须使用一个空格,参数列表中只有参数之间可以有空格。

    方法应该像这样:

    1. - (void)doSomethingWithString:(NSString *)theString {
    2. ...
    3. }

    星号前的空格是可选的。当写新的代码时,要与先前代码保持一致。

    如果一行有非常多的参数,更好的方式是将每个参数单独拆成一行。如果使用多行,将每个参数前的冒号对齐。

    1. - (void)doSomethingWith:(GTMFoo *)theFoo
    2. rect:(NSRect)theRect
    3. interval:(float)theInterval {
    4. ...
    5. }

    当第一个关键字比其它的短时,保证下一行至少有 4 个空格的缩进。这样可以使关键字垂直对齐,而不是使用冒号对齐:

    1. - (void)short:(GTMFoo *)theFoo
    2. longKeyword:(NSRect)theRect
    3. evenLongerKeyword:(float)theInterval {
    4. ...
    5. }

    方法调用

    Tip

    方法调用应尽量保持与方法声明的格式一致。当格式的风格有多种选择时,新的代码要与已有代码保持一致。

    调用时所有参数应该在同一行:

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

    或者每行一个参数,以冒号对齐:

    1. [myObject doFooWith:arg1
    2. name:arg2
    3. error:arg3];

    不要使用下面的缩进风格:

    1. [myObject doFooWith:arg1 name:arg2 // some lines with >1 arg
    2. error:arg3];
    3.  
    4. [myObject doFooWith:arg1
    5. name:arg2 error:arg3];
    6.  
    7. [myObject doFooWith:arg1
    8. name:arg2 // aligning keywords instead of colons
    9. error:arg3];

    方法定义与方法声明一样,当关键字的长度不足以以冒号对齐时,下一行都要以四个空格进行缩进。

    1. [myObj short:arg1
    2. longKeyword:arg2
    3. evenLongerKeyword:arg3];

    @public 和 @private

    Tip

    @public@private 访问修饰符应该以一个空格缩进。

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

    1. @interface MyClass : NSObject {
    2. @public
    3. ...
    4. @private
    5. ...
    6. }
    7. @end

    异常

    Tip

    每个 @ 标签应该有独立的一行,在 @{} 之间需要有一个空格, @catch 与被捕捉到的异常对象的声明之间也要有一个空格。

    如果你决定使用 Objective-C 的异常,那么就按下面的格式。不过你最好先看看 避免抛出异常 了解下为什么不要使用异常。

    1. @try {
    2. foo();
    3. }
    4. @catch (NSException *ex) {
    5. bar(ex);
    6. }
    7. @finally {
    8. baz();
    9. }

    协议名

    Tip

    类型标识符和尖括号内的协议名之间,不能有任何空格。

    这条规则适用于类声明、实例变量以及方法声明。例如:

    1. @interface MyProtocoledClass : NSObject<NSWindowDelegate> {
    2. @private
    3. id<MyFancyDelegate> delegate_;
    4. }
    5. - (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
    6. @end

    块(闭包)

    Tip

    块(block)适合用在 target/selector 模式下创建回调方法时,因为它使代码更易读。块中的代码应该缩进 4 个空格。

    取决于块的长度,下列都是合理的风格准则:

    • 如果一行可以写完块,则没必要换行。
    • 如果不得不换行,关括号应与块声明的第一个字符对齐。
    • 块内的代码须按 4 空格缩进。
    • 如果块太长,比如超过 20 行,建议把它定义成一个局部变量,然后再使用该变量。
    • 如果块不带参数,^{ 之间无须空格。如果带有参数,^( 之间无须空格,但 ) { 之间须有一个空格。
    • 块内允许按两个空格缩进,但前提是和项目的其它代码保持一致的缩进风格。
    1. // The entire block fits on one line.
    2. [operation setCompletionBlock:^{ [self onOperationDone]; }];
    3.  
    4. // The block can be put on a new line, indented four spaces, with the
    5. // closing brace aligned with the first character of the line on which
    6. // block was declared.
    7. [operation setCompletionBlock:^{
    8. [self.delegate newDataAvailable];
    9. }];
    10.  
    11. // Using a block with a C API follows the same alignment and spacing
    12. // rules as with Objective-C.
    13. dispatch_async(fileIOQueue_, ^{
    14. NSString* path = [self sessionFilePath];
    15. if (path) {
    16. // ...
    17. }
    18. });
    19.  
    20. // An example where the parameter wraps and the block declaration fits
    21. // on the same line. Note the spacing of |^(SessionWindow *window) {|
    22. // compared to |^{| above.
    23. [[SessionService sharedService]
    24. loadWindowWithCompletionBlock:^(SessionWindow *window) {
    25. if (window) {
    26. [self windowDidLoad:window];
    27. } else {
    28. [self errorLoadingWindow];
    29. }
    30. }];
    31.  
    32. // An example where the parameter wraps and the block declaration does
    33. // not fit on the same line as the name.
    34. [[SessionService sharedService]
    35. loadWindowWithCompletionBlock:
    36. ^(SessionWindow *window) {
    37. if (window) {
    38. [self windowDidLoad:window];
    39. } else {
    40. [self errorLoadingWindow];
    41. }
    42. }];
    43.  
    44. // Large blocks can be declared out-of-line.
    45. void (^largeBlock)(void) = ^{
    46. // ...
    47. };
    48. [operationQueue_ addOperationWithBlock:largeBlock];

    原文: https://zh-google-styleguide.readthedocs.io/en/latest/google-objc-styleguide/spacing/