英文原文:Google Objective-C Style Guide
注意事项显示在本指南中的隐藏细节 这个风格指南包含很多最初不可见的细节。它们被标记为三角形图标,你可以在左边看到。现在点击它,你应该会看到“万岁”出现在下面。 背景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的一般建议的自然组合。因此,在读这本指南之前,确定你已经度过:
注意:所有在Google C++指南中禁用的在Objective-C++里也一样,除非本文特别指出。 |
这个文档是为了描述用于所有Mac OS X代码中的Objective-C(和Objective-C++)编码指南和实践的。这些指南的很多地方已经进化并在其他项目和团队已经过时。谷歌开发的开源项目符合本指南中的要求。 谷歌已经发布了符合这些准则的,作为Mac项目的谷歌工具箱(以下简称GTM)的一部分的开源代码。意味着要在不同项目共享的代码是一个包含在这个库中很好的候选。 注意:这本指南不是一个Objective-C教程。我们假设读者对这么语言很熟悉。如果你是一个Objective-C初学者或需要复习,请阅读的Objective-C编程语言这本书。 |
例子他们说一个例子胜过千言万语,让我们开始用一个例子让你感受Objective-C的风格,间距,命名等。 一个头文件的例子,展示了@interface声明的正确注释和间距:
除非interface或implementation很短,比如,当定义一小部分私有方法或一个桥接类时,添加空行通常有利于可读性。 |
命名命名规则对于代码的可维护性是非常重要的。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++命名规范。这就避免了在一个函数中实例变量和本地变量的命名规则混合使用的情况,减少了对代码的可阅读性造成的极大损害。 |
注释尽管写的时候很痛苦,但是他们对于保持你代码的可读性来说绝对是至关重要的。下面几条规则描述了你应该什么时候在什么地方加注释。但是要记住,虽然注释很重要,但是最好的代码都是自注释的。给变量和类型一个有意义的名字,要比用一个难懂的名字然后再费力的用注释来解释好得多。 写注释的时候,要写给你的读者:下一个要读懂你代码的贡献者。多写点吧——下个没准就是你自己! 记住所有c++编程规范里列出的规则和协定在这里也是生效的,下面是几点补充。 |
Cocoa和Objective-C的特性
被申明在头文件的变量必须是私有的 当变量被申明在头文件时,这个变量必须被标记为@private 标识初始化器 要描述或者标识好初始化器 重写初始化器 当你写一个包含init()方法的的子类时,一定要确定重写了父类的初始化器 重写NSObject方法的位置 强连建议将重写NSObject的方法放到@implementation注记的上面 初始化 不要在init方法中把变量初始化为0或者nil,这样做完全是多余的 避免处理new方法 不要尝试调用NSObject类的new()方法,也不要在他的子类中复写这个方法。我们可以利用他的init方法来实例化这些保留对象 保持公有API简单 要保持你的类尽量简单:避免过分渲染APIs.如果有的方法没必要公开,那就不要公开.要利用private去避免把公有头弄得杂乱 #import 和 #include 要引入Objective-C/Object-C++头文件时用#import;要引入C/C++头文件时用#include. 利用跟框架 在独立文件之上应该包含跟框架 创建完了即可销毁释放 当创建一些临时对象时,在创建的那一行销毁并释放比在同一个方法内下创建然后过一会儿销毁更好 释放并保留 对象的业务遵循释放并保持规则 在执行init或者dealloc方法时避免访问器 当init和dealloc方法正在执行时,子类的实例化可能处在一个不稳定的状态,所以在这些方法中的代码尽量避免调用其他访问器 |
属性 ▶在下列情况下请注意,直接使用@property注解是被允许的:属性是将会限制你代码允许在iPhone和Mac OS X 10.5(雪豹)以上版本的Objective-C 2.0的特性。点符号只有声明@property才允许被访问。 没有示例变量的接口 ▶接口中除了空大括号之外,请不要声明任何实例变量。 自动合成实例变量 ▶使用自动合成实例变量是被允许的。编写的代码必须支持更早之前的编译工具链版本(Xcode 4.3或更早的版本亦或GCC编译)或者应该直接使用@synthesize注解调用从协议中继承来的属性。 |
自动引用计数(ARC)▶由于项目使用的是Xcode 4.2或更高版本,并将只运行在64位版Mac OS X 10.7 和 iOS 5.0及更高版本中,ARC 是优先的。手动引用计数在支持早期环境中的归零弱指针时将不可用。 需要 ARC 的类应该包含一个预处理指令来防止编译使用手动引用计数。 象 __unsafe _unretained 和 __weak 的所有权限定符应该在变量名的前面。没必要为变量指定 __strong,因为它是默认的。另一方面,属性应该始终指定 strong 关键字而不是依赖于编译器的默认值。 被编译的文件使用 ARC 时需要有预处理指令以防止编译没有 ARC。请参见下方的代码片段以了解详情。 |
NSNumber字面值▶对于利用Xcode4.4或以上版本创建的C语言项目来说,运用NSNumber字面值是被允许的。然而使用这种做法将会限制你代码对于其他工具链的可移植性。 Cocoa模式 委派模式 ▶委派对象不应该被保留。 模型、视图、控制器 ▶将模型从视图中分离。将控制器从视图和模型中分离。使用@protocols注解回调APIs。 历史说明 后缀下划线 vs 前置下划线 ▶后缀下划线曾经用于表示示例变量的名称。 |