Google 的 Objective-C 代码规范指南
注意事项
显示在本指南中的隐藏细节
这个风格指南包含很多最初不可见的细节。它们被标记为三角形图标,你可以在左边看到。现在点击它,你应该会看到“万岁”出现在下面。
背景
Objective-C是一种很动态的、面向对象的C语言扩展。它被设计成易用易读,同时支持复杂的面向对象设计。它是Mac OS X和iPhone上开发新应用的主要开发语言
Cocoa是在Mac OS X平台上的一个主要的应用框架。这是一个提供给全功能Mac OS X应用程序的快速开发的Objective-C类集合。
Apple已经为Objective-C编写了一本很好的、被广泛接受的编码指南;Google也为C++写了一本类似的指南。这本Objective-C指南意在成为一个对Apple和Google的一般建议的自然组合。因此,在读这本指南之前,确定你已经度过:
Apple的Cocoa编码指南
Google的开源C++设计指南
注意:所有在Google C++指南中禁用的在Objective-C++里也一样,除非本文特别指出。
这个文档是为了描述用于所有Mac OS X代码中的Objective-C(和Objective-C++)编码指南和实践的。这些指南的很多地方已经进化并在其他项目和团队已经过时。谷歌开发的开源项目符合本指南中的要求。
谷歌已经发布了符合这些准则的,作为Mac项目的谷歌工具箱(以下简称GTM)的一部分的开源代码。意味着要在不同项目共享的代码是一个包含在这个库中很好的候选。
注意:这本指南不是一个Objective-C教程。我们假设读者对这么语言很熟悉。如果你是一个Objective-C初学者或需要复习,请阅读的Objective-C编程语言这本书。
例子
他们说一个例子胜过千言万语,让我们开始用一个例子让你感受Objective-C的风格,间距,命名等。
一个头文件的例子,展示了@inte易做图ce声明的正确注释和间距:
01 #import <Foundation/Foundation.h>
02
03 // A sample class demonstrating good Objective-C style. All inte易做图ces,
04 // categories, and protocols (read: all top-level declarations in a header)
05 // MUST be commented. Comments must also be adjacent to the object they're
06 // documenting.
07 //
08 // (no blank line between this comment and the inte易做图ce)
09 @inte易做图ce Foo : NSObject {
10 @private
11 NSString *_bar;
12 NSString *_bam;
13 }
14
15 // Returns an autoreleased instance of Foo. See -initWithBar: for details
16 // about |bar|.
17 + (id)fooWithBar:(NSString *)bar;
18
19 // Designated initializer. |bar| is a thing that represents a thing that
20 // does a thing.
21 - (id)initWithBar:(NSString *)bar;
22
23 // Gets and sets |_bar|.
24 - (NSString *)bar;
25 - (void)setBar:(NSString *)bar;
26
27 // Does some work with |blah| and returns YES if the work was completed
28 // successfully, and NO otherwise.
29 - (BOOL)doWorkWithBlah:(NSString *)blah;
30
31 @end
一个源文件的例子,展示了一个接口的@implementation的正确注释和间距。它也包含一些重要方法,像getters、setters、init和dealloc的参考实现: 01 #import "Foo.h"
02
03
04 @implementation Foo
05
06 + (id)fooWithBar:(NSString *)bar {
07 return [[[self alloc] initWithBar:bar] autorelease];
08 }
09
10 // Must always override super's designated initializer.
11 - (id)init {
12 return [self initWithBar:nil];
13 }
14
15 - (id)initWithBar:(NSString *)bar {
16 if ((self = [super init])) {
17 _bar = [bar copy];
18 _bam = [[NSString alloc] initWithFormat:@"hi %d", 3];
19 }
20 return self;
21 }
22
23 - (void)dealloc {
24 [_bar release];
25 [_bam release];
26 [super dealloc];
27 }
28
29 - (NSString *)bar {
30 return _bar;
31 }
32
33 - (void)setBar:(NSString *)bar {
34 [_bar autorelease];
35 _bar = [bar copy];
36 }
37
38 - (BOOL)doWorkWithBlah:(NSString *)blah {
39 // ...
40 return NO;
41 }
42
43 @end
在@inte易做图ce、@implementation和@end前后的空行是可选的。如果你的@inte易做图ce声明了实参,那么右括号之后需要有一个空行。
除非inte易做图ce或implementation很短,比如,当定义一小部分私有方法或一个桥接类时,添加空行通常有利于可读性。
间距和格式
空格(spacing)与制表符(tab)
▶
仅使用空格,每次缩进2个空格。
每行的宽度
▶
应尽量在你的代码中将每行控制在80个字符内。
方法的声明和定义
▶
在-(或+)与返回值类型中间须要有一个空格,在参数列表中,除了参数之间不要有任何间距。
方法调用
▶
方法调用的格式须要与定义时个格式一致。当有多种格式化的样式可供选择的时候,按照惯例,采用在给定的源文件中使用过的那个方式。
@public与@private
▶
@public与@private访问修饰符后边须要有一个空格。
Exceptions
▶
在单独一行时,使用 @ 标签格式化 exceptions,@ 标签和开放括号 ({) 间加一个空格,在@catch 和 对象捕获声明之间也是。
Protocols
▶
在类型标识符和封装在尖括号中的 Protocols 名称之间不应该有空格。
Blocks
▶
Blocks 在创建回调函数时更倾向于目标选择器模式,这可以让代码更易读。块内的代码应缩进4个空格。
命名
命名规则对于代码的可维护性是非常重要的。Objective-C的方法命名趋向于超长命名,但这会带来良好的代码阅读感受,就像读散文一样,同时还避免了很多不必要的注释。
在撰写纯粹的Objective-C代码时,我们主要是遵循标准的Objective-C命名规范。这些命名方针可能和C++的命名规范相去甚远。比如,Google的C++规范中推荐在变量名中的单词间使用下划线,而Objective-C的规范推荐使用驼峰命名法,这也是在Objective-C社区中的标准做法。
任何类、目录、方法或者变量的名字都应该将其中的首字母缩略词设为大写。下面是苹果官方使用的大写的首字母缩略词:URL,TIFF和EXIF。
然而,在编写Objective-C++代码时,往往并非能完全按照规范来进行。很多项目会使用Objective-C,或是Cocoa,或是C++后端与原生的Cocoa前端通信的方式来实现跨平台的C++ API。这就导致了两种语言规范直接冲突的情况。
我们的解决方法是依据方法/函数具体实现的方式来决定命名。如果你在一个@implementationblock里面,就使用Objective-C的命名规范。如果你在一个C++类里面实现一个方法,就使用C++命名规范。这就避免了在一个函数中实例变量和本地变量的命名规则混合使用的情况,减少了对代码的可阅读性造成的极大损害。
文件名
▶
文件名应该反映其中包含的类实现的名称,按照你项目中的约定且大小写相关。
Objective-C++
▶
在一个源码文件中, Objective-C++ 遵循你实现的函数/方法的风格。
类名
▶
类名(类别和协议名称)应为大写,并开始使用大小写混合以区分单词。
分类名称
▶
分类名称应该以一个2到3个字母的前缀开始,识别分类是项目的一部分,还是打开使用。分类,名称应该结合它扩展的类的名称。
Objective-C 方法名称
▶
方法名称应该以小写字母开头,混合大小写。每个命名参数也应该以小写字母开头。
变量名
▶
变量名以小写字母开头,混合大小写以区分单词。实例变量以下划线开头。例如:myLocalVariable,_myInstanceVariable。
注释
尽管写的时候很痛苦,但是他们对于保持你代码的可读性来说绝对是至关重要的。下面几条规则描述了你应该什么时候在什么地方加注释。但是要记住,虽然注释很重要,但是最好的代码都是自注释的。给变量和类型一个有意义的名字,要比用一个难懂的名字然后再费力的用注释来解释好得多。
写注释的时候,要写给你的读者:下一个要读懂你代码的贡献者。多写点吧——下个没准就是你自己!
记住所有c++编程规范里列出的规则和协定在这里也是生效的,下面是几点补充。
File Comments文件注释
▶
可以有选
补充:移动开发 , IOS ,