Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 43 additions & 43 deletions OC代码规范总结.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Objective-C编码规范,内容来自苹果、谷歌的文档翻译,[『博

转载请注明出处。

##概要
## 概要

Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和Mac应用程序。关于Objective-C的编码规范,苹果和谷歌都已经有很好的总结:

Expand All @@ -14,17 +14,17 @@ Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和
本文主要整合了对上述文档的翻译、作者自己的编程经验和其他的相关资料,为公司总结出一份通用的编码规范。


##代码格式
## 代码格式

###使用空格而不是制表符Tab
### 使用空格而不是制表符Tab

不要在工程里使用Tab键,使用空格来进行缩进。在`Xcode > Preferences > Text Editing`将Tab和自动缩进都设置为**4**个空格。(_Google的标准是使用两个空格来缩进,但这里还是推荐使用Xcode默认的设置。_)

###每一行的最大长度
### 每一行的最大长度

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

###函数的书写
### 函数的书写

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

Expand Down Expand Up @@ -62,7 +62,7 @@ Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和
...
}
```
###函数调用
### 函数调用

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

Expand Down Expand Up @@ -97,7 +97,7 @@ Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和
error:arg3];
```

###@public和@private标记符
### @public和@private标记符

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

Expand All @@ -111,7 +111,7 @@ Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和
@end
```

###协议(Protocols)
### 协议(Protocols)

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

Expand All @@ -125,7 +125,7 @@ Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和
@end
```

###闭包(Blocks)
### 闭包(Blocks)

根据block的长度,有不同的书写规则:

Expand Down Expand Up @@ -189,7 +189,7 @@ void (^largeBlock)(void) = ^{
}];
```

###数据结构的语法糖
### 数据结构的语法糖

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

Expand Down Expand Up @@ -253,11 +253,11 @@ NSDictionary *stillWrong = @{
};
```

##命名规范
## 命名规范

###基本原则
### 基本原则

####清晰
#### 清晰

命名应该尽可能的清晰和简洁,但在Objective-C中,清晰比简洁更重要。由于Xcode强大的自动补全功能,我们不必担心名称过长的问题。

Expand Down Expand Up @@ -310,11 +310,11 @@ sendPort
displayName
```

####一致性
#### 一致性

整个工程的命名风格要保持一致性,最好和苹果SDK的代码保持统一。不同类中完成相似功能的方法应该叫一样的名字,比如我们总是用`count`来返回集合的个数,不能在A类中使用`count`而在B类中使用`getNumber`。

###使用前缀
### 使用前缀

如果代码需要打包成Framework给别的工程使用,或者工程项目非常庞大,需要拆分成不同的模块,使用命名前缀是非常有用的。

Expand All @@ -324,15 +324,15 @@ displayName

- 命名前缀的时候不要和苹果SDK框架冲突。

###命名类和协议(Class&Protocol)
### 命名类和协议(Class&Protocol)

类名以大写字母开头,应该包含一个*名词*来表示它代表的对象类型,同时可以加上必要的前缀,比如`NSString`, `NSDate`, `NSScanner`, `NSApplication`等等。

而协议名称应该清晰地表示它所执行的行为,而且要和类名区别开来,所以通常使用`ing`词尾来命名一个协议,比如`NSCopying`,`NSLocking`。

有些协议本身包含了很多不相关的功能,主要用来为某一特定类服务,这时候可以直接用类名来命名这个协议,比如`NSObject`协议,它包含了id对象在生存周期内的一系列方法。

###命名头文件(Headers)
### 命名头文件(Headers)

源码的头文件名应该清晰地暗示它的功能和包含的内容:

Expand All @@ -344,7 +344,7 @@ displayName

- Framework中有时候会实现在别的框架中类的类别扩展,这样的文件通常使用`被扩展的框架名`+`Additions`的方式来命名,比如`NSBundleAdditions.h`。

###命名方法(Methods)
### 命名方法(Methods)

Objective-C的方法名通常都比较长,这是为了让程序有更好地可读性,按苹果的说法*“好的方法名应当可以以一个句子的形式朗读出来”*。

Expand Down Expand Up @@ -424,7 +424,7 @@ Objective-C的方法名通常都比较长,这是为了让程序有更好地可
...title:(NSString *)aString
```

###存取方法(Accessor Methods)
### 存取方法(Accessor Methods)

存取方法是指用来获取和设置类属性值的方法,属性的不同类型,对应着不同的存取方法规范:

Expand Down Expand Up @@ -481,7 +481,7 @@ Objective-C的方法名通常都比较长,这是为了让程序有更好地可
- (void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase;
```

###命名委托(Delegate)
### 命名委托(Delegate)

当特定的事件发生时,对象会触发它注册的委托方法。委托是Objective-C中常用的传递消息的方式。委托有它固定的命名范式。

Expand All @@ -504,7 +504,7 @@ Objective-C的方法名通常都比较长,这是为了让程序有更好地可
- (BOOL)windowShouldClose:(id)sender;
```

###集合操作类方法(Collection Methods)
### 集合操作类方法(Collection Methods)

有些对象管理着一系列其它对象或者元素的集合,需要使用类似“增删查改”的方法来对集合进行操作,这些方法的命名范式一般为:

Expand Down Expand Up @@ -539,7 +539,7 @@ Objective-C的方法名通常都比较长,这是为了让程序有更好地可
- (void)setParentWindow:(NSWindow *)window;
```

###命名函数(Functions)
### 命名函数(Functions)

在很多场合仍然需要用到函数,比如说如果一个对象是一个单例,那么应该使用函数来代替类方法执行相关操作。

Expand Down Expand Up @@ -574,7 +574,7 @@ const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep, unsi
BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)
```

###命名属性和实例变量(Properties&Instance Variables)
### 命名属性和实例变量(Properties&Instance Variables)

属性和对象的存取方法相关联,属性的第一个字母小写,后续单词首字母大写,不必添加前缀。属性按功能命名成名词或者动词:

Expand Down Expand Up @@ -605,7 +605,7 @@ BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)
*按苹果的说法,不建议在除了`init`和`dealloc`方法以外的地方直接访问实例变量,但很多人认为直接访问会让代码更加清晰可读,只在需要计算或者执行操作的时候才使用存取方法访问,我就是这种习惯,所以这里不作要求。*


###命名常量(Constants)
### 命名常量(Constants)

如果要定义一组相关的常量,尽量使用枚举类型(enumerations),枚举类型的命名规则和函数的命名规则相同。
建议使用 `NS_ENUM` 和 `NS_OPTIONS` 宏来定义枚举类型,参见官方的 [Adopting Modern Objective-C](https://developer.apple.com/library/ios/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html) 一文:
Expand Down Expand Up @@ -646,7 +646,7 @@ const float NSLightGray;

注意到一般由编译器定义的宏会在前后都有一个`__`,比如*`__MACH__`*。

###命名通知(Notifications)
### 命名通知(Notifications)

通知常用于在模块间传递消息,所以通知要尽可能地表示出发生的事件,通知的命名范式是:

Expand All @@ -661,11 +661,11 @@ NSTextViewDidChangeSelectionNotification
NSColorPanelColorDidChangeNotification
```

##注释
## 注释

读没有注释代码的痛苦你我都体会过,好的注释不仅能让人轻松读懂你的程序,还能提升代码的逼格。注意注释是为了让别人看懂,而不是仅仅你自己。

###文件注释
### 文件注释

每一个文件都**必须**写文件注释,文件注释通常包含

Expand Down Expand Up @@ -714,7 +714,7 @@ NSColorPanelColorDidChangeNotification

*文件注释的格式通常不作要求,能清晰易读就可以了,但在整个工程中风格要统一。*

###代码注释
### 代码注释

好的代码应该是“自解释”(self-documenting)的,但仍然需要详细的注释来说明参数的意义、返回值、功能以及可能的副作用。

Expand Down Expand Up @@ -775,19 +775,19 @@ NSColorPanelColorDidChangeNotification

**定义在头文件里的接口方法、属性必须要有注释!**

##编码风格
## 编码风格

每个人都有自己的编码风格,这里总结了一些比较好的Cocoa编程风格和注意点。

###不要使用new方法
### 不要使用new方法

尽管很多时候能用`new`代替`alloc init`方法,但这可能会导致调试内存时出现不可预料的问题。Cocoa的规范就是使用`alloc init`方法,使用`new`会让一些读者困惑。

###Public API要尽量简洁
### Public API要尽量简洁

共有接口要设计的简洁,满足核心的功能需求就可以了。不要设计很少会被用到,但是参数极其复杂的API。如果要定义复杂的方法,使用类别或者类扩展。

###\#import和\#include
### \#import和\#include

`#import`是Cocoa中常用的引用头文件的方式,它能自动防止重复引用文件,什么时候使用`#import`,什么时候使用`#include`呢?

Expand All @@ -805,7 +805,7 @@ NSColorPanelColorDidChangeNotification

为什么不全部使用`#import`呢?主要是为了保证代码在不同平台间共享时不出现问题。

###引用框架的根头文件
### 引用框架的根头文件

上面提到过,每一个框架都会有一个和框架同名的头文件,它包含了框架内接口的所有引用,在使用框架的时候,应该直接引用这个根头文件,而不是其它子模块的头文件,即使是你只用到了其中的一小部分,编译器会自动完成优化的。

Expand All @@ -818,7 +818,7 @@ NSColorPanelColorDidChangeNotification
#import <Foundation/NSString.h>
```

###BOOL的使用
### BOOL的使用

BOOL在Objective-C中被定义为`signed char`类型,这意味着一个BOOL类型的变量不仅仅可以表示`YES`(1)和`NO`(0)两个值,所以永远**不要**将BOOL类型变量直接和`YES`比较:

Expand Down Expand Up @@ -861,11 +861,11 @@ if (great)

另外BOOL类型可以和`_Bool`,`bool`相互转化,但是**不能**和`Boolean`转化。

###使用ARC
### 使用ARC

除非想要兼容一些古董级的机器和操作系统,我们没有理由放弃使用ARC。在最新版的Xcode(6.2)中,ARC是自动打开的,所以直接使用就好了。

###在init和dealloc中不要用存取方法访问实例变量
### 在init和dealloc中不要用存取方法访问实例变量

当`init``dealloc`方法被执行时,类的运行时环境不是处于正常状态的,使用存取方法访问变量可能会导致不可预料的结果,因此应当在这两个方法内直接访问实例变量。

Expand Down Expand Up @@ -897,11 +897,11 @@ if (great)
}
```

###按照定义的顺序释放资源
### 按照定义的顺序释放资源

在类或者Controller的生命周期结束时,往往需要做一些扫尾工作,比如释放资源,停止线程等,这些扫尾工作的释放顺序应当与它们的初始化或者定义的顺序保持一致。这样做是为了方便调试时寻找错误,也能防止遗漏。

###保证NSString在赋值时被复制
### 保证NSString在赋值时被复制

`NSString`非常常用,在它被传递或者赋值时应当保证是以复制(copy)的方式进行的,这样可以防止在不知情的情况下String的值被其它对象修改。

Expand All @@ -911,7 +911,7 @@ if (great)
}
```

###使用NSNumber的语法糖
### 使用NSNumber的语法糖

使用带有`@`符号的语法糖来生成NSNumber对象能使代码更简洁:

Expand All @@ -924,7 +924,7 @@ enum {
NSNumber *myEnum = @(kMyEnum);
```

###nil检查
### nil检查

因为在Objective-C中向nil对象发送命令是不会抛出异常或者导致崩溃的,只是完全的“什么都不干”,所以,只在程序中使用nil来做逻辑上的检查。

Expand All @@ -942,11 +942,11 @@ if (nil == objc) {
}
```

###属性的线程安全
### 属性的线程安全

定义一个属性时,编译器会自动生成线程安全的存取方法(Atomic),但这样会大大降低性能,特别是对于那些需要频繁存取的属性来说,是极大的浪费。所以如果定义的属性不需要线程保护,记得手动添加属性关键字`nonatomic`来取消编译器的优化。

###点分语法的使用
### 点分语法的使用

不要用点分语法来调用方法,只用来访问属性。这样是为了防止代码可读性问题。

Expand All @@ -961,7 +961,7 @@ NSUInteger numberOfItems = array.count;
array.release;
```

###Delegate要使用弱引用
### Delegate要使用弱引用

一个类的Delegate对象通常还引用着类本身,这样很容易造成引用循环的问题,所以类的Delegate属性要设置为弱引用。

Expand Down
6 changes: 3 additions & 3 deletions Pods/BAButton/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Pods/BACustomAlertView/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Pods/IQKeyboardManager/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading