每一行的最大长度

    同样的,在Xcode > Preferences > Text Editing > Page guide at column:中将最大行长设置为80,过长的一行代码将会导致可读性问题。

    一个典型的Objective-C函数应该是这样的:

    -(void)之间应该有一个空格,第一个大括号{的位置在函数所在行的末尾,同样应该有一个空格。(我司的C语言规范要求是第一个大括号单独占一行,但考虑到OC较长的函数名和苹果SDK代码的风格,还是将大括号放在行末。

    如果一个函数有特别多的参数或者名称很长,应该将其按照:来对齐分行显示:

    1. -(id)initWithModel:(IPCModle)model
    2. ConnectType:(IPCConnectType)connectType
    3. Resolution:(IPCResolution)resolution
    4. AuthName:(NSString *)authName
    5. Password:(NSString *)password
    6. MAC:(NSString *)mac
    7. AzIp:(NSString *)az_ip
    8. AzDns:(NSString *)az_dns
    9. Token:(NSString *)token
    10. Email:(NSString *)email
    11. Delegate:(id<IPCConnectHandlerDelegate>)delegate;
    1. - (void)short:(GTMFoo *)theFoo
    2. longKeyword:(NSRect)theRect
    3. evenLongerKeyword:(float)theInterval
    4. error:(NSError **)theError {
    5. ...
    6. }

    函数调用

    函数调用的格式和书写差不多,可以按照函数的长短来选择写在一行或者分成多行:

    以下写法是错误的:

    1. //错误,要么写在一行,要么全部分行
    2. [myObject doFooWith:arg1 name:arg2
    3. error:arg3];
    4. [myObject doFooWith:arg1
    5. name:arg2 error:arg3];
    6. //错误,按照':'来对齐,而不是关键字
    7. [myObject doFooWith:arg1
    8. name:arg2
    9. error:arg3];

    @private标记符应该以一个空格来进行缩进:

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

    协议(Protocols)

    在书写协议的时候注意用<>括起来的协议和类型名之间是没有空格的,比如IPCConnectHandler()<IPCPreconnectorDelegate>,这个规则适用所有书写协议的地方,包括函数声明、类声明、实例变量等等:

    • 较短的block可以写在一行内。
    • block内的代码采用4个空格的缩进。
    • 如果block过于庞大,应该单独声明成一个变量来使用。
    • ^(之间,^{之间都没有空格,参数列表的右括号和{之间有一个空格。
    1. //较短的block写在一行内
    2. [operation setCompletionBlock:^{ [self onOperationDone]; }];
    3. //分行书写的block,内部使用4空格缩进
    4. [operation setCompletionBlock:^{
    5. [self.delegate newDataAvailable];
    6. }];
    7. //使用C语言API调用的block遵循同样的书写规则
    8. dispatch_async(_fileIOQueue, ^{
    9. NSString* path = [self sessionFilePath];
    10. if (path) {
    11. // ...
    12. }
    13. });
    14. //较长的block关键字可以缩进后在新行书写,注意block的右括号'}'和调用block那行代码的第一个非空字符对齐
    15. [[SessionService sharedService]
    16. loadWindowWithCompletionBlock:^(SessionWindow *window) {
    17. if (window) {
    18. [self windowDidLoad:window];
    19. } else {
    20. [self errorLoadingWindow];
    21. }
    22. }];
    23. //较长的block参数列表同样可以缩进后在新行书写
    24. [[SessionService sharedService]
    25. loadWindowWithCompletionBlock:
    26. ^(SessionWindow *window) {
    27. if (window) {
    28. [self windowDidLoad:window];
    29. } else {
    30. [self errorLoadingWindow];
    31. }
    32. }];
    33. //庞大的block应该单独定义成变量使用
    34. void (^largeBlock)(void) = ^{
    35. // ...
    36. [_operationQueue addOperationWithBlock:largeBlock];
    37. //在一个调用中使用多个block,注意到他们不是像函数那样通过':'对齐的,而是同时进行了4个空格的缩进
    38. [myObject doSomethingWith:arg1
    39. // ...
    40. }
    41. secondBlock:^(Bar *b) {
    42. // ...
    43. }];

    数据结构的语法糖

    应该使用可读性更好的语法糖来构造NSArrayNSDictionary等数据结构,避免使用冗长的alloc,init方法。

    如果构造代码写在一行,需要在括号两端留有一个空格,使得被构造的元素于与构造语法区分开来:

    1. //正确,在语法糖的"[]"或者"{}"两端留有空格
    2. NSArray *array = @[ [foo description], @"Another String", [bar description] ];
    3. NSDictionary *dict = @{ NSForegroundColorAttributeName : [NSColor redColor] };
    4. //不正确,不留有空格降低了可读性
    5. NSArray* array = @[[foo description], [bar description]];
    6. NSDictionary* dict = @{NSForegroundColorAttributeName: [NSColor redColor]};

    如果构造代码不写在一行内,构造元素需要使用两个空格来进行缩进,右括号]或者}写在新的一行,并且与调用语法糖那行代码的第一个非空字符对齐:

    构造字典时,字典的Key和Value与中间的冒号:都要留有一个空格,多行书写时,也可以将Value对齐:

    1. //正确,冒号':'前后留有一个空格
    2. NSDictionary *option1 = @{
    3. NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12],
    4. NSForegroundColorAttributeName : fontColor
    5. };
    6. //正确,按照Value来对齐
    7. NSDictionary *option2 = @{
    8. NSFontAttributeName : [NSFont fontWithName:@"Arial" size:12],
    9. NSForegroundColorAttributeName : fontColor
    10. };
    11. //错误,冒号前应该有一个空格
    12. NSDictionary *wrong = @{
    13. AKey: @"b",
    14. BLongerKey: @"c",
    15. };
    16. //错误,每一个元素要么单独成为一行,要么全部写在一行内
    17. NSDictionary *alsoWrong= @{ AKey : @"a",
    18. BLongerKey : @"b" };
    19. //错误,在冒号前只能有一个空格,冒号后才可以考虑按照Value对齐
    20. NSDictionary *stillWrong = @{
    21. AKey : @"b",
    22. BLongerKey : @"c",