一、前言
本规范基于Google Objective-C Style Guide,对其中的说明性语句及非ARC部分进行了删减。每项规范前面的 [强制]
代表该规范需要强制执行,[建议]
代表推荐执行但不强制。
二、缩进与格式
- 2.1、缩进符
[强制]
只用空格,用4个空格表示一个缩进。
选中多行或者一行来使用快捷键control + I
自动缩进
- 2.2、每行的长度
[建议]
应尽量控制每行代码的长度在120
个字符以内.
xcode > preferences > text editing > page guide at column: 中将最大行长设置为 80 ,过长的一行代码将会导致可读性问题。 - 2.3、逗号分隔项
[强制]
用逗号分隔多项时,每个逗号后使用1个空格进行分隔,如下数组,one、two 后面的逗号加空格,以此类推:字典等等都一样
NSArray *array = @[@"one", @"two", @"three"];
- 2.4、左大括号位置
[建议]
左大括号{
不单独占据一行,放置在上一行的末尾,可以在{
前增加一个空格,如下
- 2.5、声明与定义
[强制]
-、+ 与返回类型之间必须有一个空格,在参数列表中,除了参数之间不要有任何间距,如下
- (void)doSomethingWithString:(NSString *)string { ...... }
[强制]
* 号前面必须要加空格,增加可读性。[建议]
如果有参数太多无法放在同一行内, 最好每个参数各自一行;如果采用多行,每个参数建议按照 : 进行对齐。如下
- (void)doSomethingWithString1:(NSString *)string1 string2:(NSString *)string2 string3:(NSString *)string3 { ...... }
[建议]
当第一个关键词比其他的短时,可以缩进之后的行至少4个空格,同样按 : 进行对齐,如下
- (void)short:(GTMFoo *)theFoo longKeyword:(NSRect)theRect evenLongerKeyword:(float)theInterval error:(NSError **)theError { ...... }
- 2.6、方法调用
[建议]
方法调用的格式须要与定义时的格式一致。当有多种格式化的样式可供选择的时候,按照惯例,采用在给定的源文件中使用过的那个方式。[建议]
所有的参数都应该在同一行
举例如下:
[myObject doSomethingWithString1:arg1 string2:arg2 string3:arg3];
- 分析:或者每个参数一行,并按 : 对齐,举例如下
[myObject doSomethingWithString1:arg1 string2:arg2 string3:arg3];
- 不建议采用以下风格,举例如下,不规范的原因:第一行写了两个参数 和 第二行两个参数
[myObject doSomethingWithString1:arg1 string2:arg2 string3:arg3]; [myObject doSomethingWithString1:arg1 string2:arg2 string3:arg3];
- 拓展:就像声明和定义一样,当第一个关键词比其他的短时,可以缩进之后的行至少4个空格,同样按 : 进行对齐,举例如下
[myObj short:arg1 longKeyword:arg2 evenLongerKeyword:arg3 error:arg4];
补充:调用中如果有包含内联的 block 也可以缩进至少4个空格,然后左对齐。
- 2.7、@public、@protected 与 @private
[强制]
访问修饰符 @public, @private,@protected必须缩进2个空格。 - 2.8、异常
[建议]
在单独一行时,使用 @ 标签格式化 exceptions, @ 标签和左大括号 { 间加一个空格,在 @catch 和 对象捕获声明之间也一样。建议遵循下面的格式
@try { foo(); } @catch (NSException *ex) { bar(ex); } @finally { baz(); }
- 2.9、协议
[强制]
在类型标识符和封装在尖括号中的 Protocols 名称之间要有空格。如下
@interface MyProtocoledClass : NSObject <NSWindowDelegate> { @private id <MyFancyDelegate> delegate_; } - (void)setDelegate:(id <MyFancyDelegate>)aDelegate; @end
- 2.10、Blocks
[强制]
块内的代码应缩进4个空格。[建议]
因为具体block长度的不同,可以有以下几种风格:
- 如果block一行就能放下,就不需要换行
- 如果必须要换行,那么 } 需要和block所在行的第一个字符对齐
block中的代码块应该缩进4个空格。 - 如果block很大,比如超过20行,建议单独拿出来赋给一个本地变量
- 如果block没有参数,那字符 ^{ 之间就不应有空格。如果有参数,字符 ^{ 之间同样没有空格,但是字符 ) { 之间需要有一个空格。
- 包含内联block的函数调用可以在缩进4个空格的基础上左对齐,尤其是调用中包含多个内联block。
- 举例如下:
<1>、整个block放在一行的
[operation setCompletionBlock:^{ [self onOperationDone]; }];
- <2>、多行时缩进四个空格,{要和block所在行的第一个字符对齐
[operation setCompletionBlock:^{ [self.delegate newDataAvailable]; }];
- <3>、在C函数中使用block时遵循和Objective-C同样的对齐和缩进原则
dispatch_async(fileIOQueue_, ^{ NSString *path = [self sessionFilePath]; if (path) { // ... } });
- <4>、方法参数与block声明能放到一行时。注意比较^(SessionWindow *window) {和上面的^{。
[[SessionService sharedService] loadWindowWithCompletionBlock:^(SessionWindow *window) { if (window) { [self windowDidLoad:window]; } else { [self errorLoadingWindow]; } }];
- <5>、方法参数与block声明不能放到一行时
[[SessionService sharedService] loadWindowWithCompletionBlock: ^(SessionWindow *window) { if (window) { [self windowDidLoad:window]; } else { [self errorLoadingWindow]; } }];
- <6>、较长的Block可声明为变量
void (^largeBlock)(void) = ^{ // ... }; [operationQueue_ addOperationWithBlock:largeBlock];
- <7>、一次调用中包含多个内联block
[myObject doSomethingWith:arg1 firstBlock:^(Foo *a) { // ... } secondBlock:^(Bar *b) { // ... }];
- 2.11、Blocks
[强制]
使用容器(数组和字典)常量,如果其内容被分为多行,应该缩进4个空格。[建议]
如果内容单行就能放下,在左大括号之后和右大括号之前各添加一个空格。
示例:
NSArray *array = @[ [foo description], @"Another String", [bar description] ]; NSDictionary *dict = @{ NSForegroundColorAttributeName : [NSColor redColor] };
[建议]
如果内容跨越多行,将左括号和声明放在同一行,之后换行的内容缩进4个空格,并将右括号单独放在新的一行里和声明行对齐。
示例:
NSArray *array = @[ @"This", @"is", @"an", @"array" ]; NSDictionary *dictionary = @{ NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12], NSForegroundColorAttributeName : fontColor };
[强制]
对于字典常量,在:
之前不加空格,之后至少一个空格(或者空格的数量能够满足对齐的要求)
示例:
NSDictionary *option1 = @{ NSFontAttributeName: [NSFont fontWithName:@"Helvetica-Bold" size:12], NSForegroundColorAttributeName: fontColor }; NSDictionary *option2 = @{ NSFontAttributeName: [NSFont fontWithName:@"Arial" size:12], NSForegroundColorAttributeName: fontColor };
- 下面的都是错误的:
示例
// :之前应该有空格 NSDictionary *wrong = @{ AKey: @"b", BLongerKey: @"c", }; // 左大括号之后的内容应该另起一行,或者都放在同一行 NSDictionary *alsoWrong= @{ AKey : @"a", BLongerKey : @"b" }; // :之前不应该有多个空格 NSDictionary *stillWrong = @{ AKey : @"b", BLongerKey : @"c", };