本文由海水的味道编译整理,转载请注明译者和出处,请勿用于商业用途!
点标记语法
属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况使用方括号标记语法。
良好的风格:
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
不良的风格:
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
间距
二元运算符和参数之间需要放置一个空格,一元运算符、强制类型转换和参数之间不放置空格。关键字之后圆括号之前需要放置一个空格。
void *ptr = &value + 10 * 3;
NewType a = (NewType)b;
for (int i = 0; i < 10; i++) {
doCoolThings();
}
数组和字典类型的字面值的方括号两边各放置一个空格。
NSArray *theShit = @[ @1, @2, @3 ];
字典字面值的键和冒号之间没有空格,冒号和值之间有一个空格。
NSDictionary *keyedShit = @{ GHDidCreateStyleGuide: @YES };
C函数声明中,左括号的前面不保留空格,并且函数名应该像类一样带有命名空间标识。
良好的风格:
void RNCwesomeFunction(BOOL hasSomeArgs);
长的字面值应被拆分为多行。
良好的风格:
NSArray *theShit = @[
@"Got some long string objects in here.",
[AndSomeModelObjects too],
@"Moar strings."
];
NSDictionary *keyedShit = @{
@"this.key": @"corresponds to this value",
@"otherKey": @"remoteData.payload",
@"some": @"more",
@"JSON": @"keys",
@"and": @"stuff",
};
每一行代码使用4个空格缩进。不使用tab缩进。下图是在Xcode的Preferences进行缩进设置的截图。
方法签名以及其他关键字(if/else/switch/while等)后面跟随的左花括号总是和语句出现于同一行,而右花括号独占一行。
良好的风格:
if (user.isHappy) {
//Do something
}
else {
//Do something else
}
如果一个方法内有多个功能区域,可以使用空行分隔功能区域。
每一行代码不要超过100个字符。
每一个方法之前都有一个99字符宽的注释行,注释行相对于使用空行更能提高代码的辨识度,当一行代码很长的时候,注释行也起到了越界检测的作用。注释行:
///////////////////////////////////////////////////////////////////////////////////////////////////
条件语句
当需要满足一定条件时才执行某项操作时,最左边缘应该是愉快路径代码。不要将愉快路径代码内嵌到if语句中。多个return是正常合理的。
良好的风格做法:
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
不良的风格:
- (void)someMethod {
if ([someOther boolValue]) {
//Do something important
}
}
所有的逻辑块必须使用花括号包围,即使条件体只需编写一行代码也必须使用花括号。
良好的风格做法:
if (!error) {
return success;
}
不良的风格:
if (!error)
return success;
或:
if (!error) return success;
三元运算符
长的三元运算符应使用圆括号括起来。三元运算符仅用于赋值和做参数。
Blah *a = (stuff == thing ? foo : bar);
合并的nil三元运算符应该尽量避免。
不良的风格:
Blah *b = thingThatCouldBeNil ?: defaultValue;
多分支条件应该使用if语句或重构为实例变量。
良好的风格:
result = a > b ? x : y;
不良的风格:
result = a > b ? x = c > d ? c : d : y;
异常和错误处理
不要在流控制语句中使用异常(NSException)。
异常仅用于表明程序员的错误。
为了表明一个错误,使用NSError *。
当一个方法通过引用返回一个错误参数,应该检测返回值的状态,而不是错误参数的状态。
良好的风格:
NSError *error;
if (![self trySomethingWithError:&error]) {
// Handle Error
}
不良的风格:
NSError *error;
[self trySomethingWithError:&error];
if (error) {
// Handle Error
}
在方法执行成功的情况下赋值非Null值给错误参数,会使路径跳转到假条件分支(随后程序奔溃)。
代理
除了继承一个类或实现一个协议,否则在头文件中仅使用类声明@class指令,不用#import导入类头文件。
如果一个delegate只有几个方法,比如只是提交和取消,推荐使用block编写动作响应代码。
使用block还是delegate编写回调代码遵循以下几点:(详见参考链接[8])
Ø 如果对象存在多个不同事件,则应该使用代理模式编写各事件的处理代码
Ø 如果对象是单例,应该使用block,而不是代理。
Ø 如果对象是为了其他的信息而进行回调,则使用代理。
Ø 代理更多的是面向于过程,而block则更多的面向于结果。
由于代理方法的声明一般都很长,所以必须将代理对象和其他的协议对象放在实例变量定义的下面,否则实例变量定义的对齐方式将会被打乱掉。
当需要实现多个协议的时候,将每一个协议名拆分到单独的行。
良好的风格:
@interface CustomModelViewController : TTViewController <
TTModelDelegate,
TTURLRequestDelegate
> {
方法
一个方法的命名首先描述返回什么,接着是什么情况下被返回。方法签名中冒号的前面描述传入参数的类型。以下类方法和实例方法命名的格式语法:
[object/class thing+而BOOL类型是8位的unsigned int,即BOOL的值不仅仅是1或0。
良好的风格:
if (!someObject) {
}
不良的风格:
if (someObject == nil) {
}
对于一个BOOL值:两种最佳实践:
if (isAwesome)
if (![someObject boolValue])
不良的风格:
if ([someObject boolValue] == NO)
if (isAwesome == YES) // Never do this.
如果一个BOOL类型的属性名是一个形容词,忽略属性名的“is”前缀是允许的,但需要为访问器指定约定的方法名,比如:
@property (assign, getter=isEditable) BOOL editable;
单例
应该使用线程安全的模式创建共享的单例实例。
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
Normal
0
10 pt
0
2
false
false
false
EN-US
ZH-CN
X-NONE
$([{£¥·‘“〈《「『【〔〖〝﹙﹛﹝$(.[{£¥
!%),.:;>?]}¢¨°·ˇˉ―‖’”…‰′″›℃∶、。〃〉》」』】〕〗〞︶︺︾﹀﹄﹚﹜﹞!"%'),.:;?]`|}~¢
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";}
单例的另一种做法,利用+ initialize方法。(JSONModel源码43行:http://t.cn/8F7uBF4):
static JSONAPI*
sharedInstance = nil;
+ (void)initialize {
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedInstance = [[JSONAPI alloc]
init];
});
}
附录
Xcode主题
大部分的开发者都使用Xcode默认的字体颜色主题,其实好的主题不仅能提高源代码的辨识度,同时也增添了编码的乐趣。以下是二款Xcode字体颜色主题链接:
https://github.com/vinhnx/Ciapre-Xcode-theme
https://github.com/tursunovic/xcode-themes
代码片段
熟练使用代码片段库可以提高编码的速度。Xcode4中,打开一个项目并让右侧编辑区可视,然后点击右侧底部面板的第四个{}图标,打开代码片段库,你可以将常用的代码拖入其中。以下是一个最新的开源代码片段库链接:
https://github.com/mattt/Xcode-Snippets
在code snippet library新建如下代码,设定一个类似vci(view controller initialize含义)自动提示快捷键。当开始编写ViewController或View时,键入vci,将相应的代码填入对应的位置。
#pragma mark - init
Method
填入init,initWithFrame等方法
#pragma mark- View
Life Cycle
填入viewdidload,viewdidappear等方法
#pragma mark-
Override Parent Methods
填入updateViewConstraints,updateConstraint, prepareForSegue等方法
#pragma mark-
SubViews Configuration
填入configureSubViews,configureTableView等方法,这里的方法在init方法或view
life cycle被调用
#pragma mark- Actions
填入-(IBAction)action:(id)sender和[self
addtarget:self action:@selector(action:)]动作指向的方法
#pragma mark- Public
Methods
填入在.h外暴露的方法
#pragma mark- Private
Methods
填入.m文件内部调用的方法
#pragma mark-
Delegate,DataSource, Callback Method
填入tableview,scrollview等代理方法
#pragma mark- Getter
Setter
填入对@property初始化的方法
#pragma mark- Helper
Method
填入一些帮助方法,如果使用扩展实现帮助方法不合适,则将帮助方法填在这里
#pragma mark
Temporary Area
填入一些你需要删除,或者不确定后面需不需要用,或者写一写备注之类的,类似代码回收站含义
参考链接
[1] 《NYTimes Objective-C Style Guide》 https://github.com/NYTimes/objective-c-style-guide
[2] 《Coding Guidelines for Cocoa》https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html
[3] 《iOS-view-frame-builder》https://github.com/rsobik/ios-view-frame-builder/commit/0fa2d81762bc21619b1503d34b7d67160f4678f8
[4] 《Cocoa Style for Objective-C: Part I》 http://cocoadevcentral.com/articles/000082.php
[5] 《Cocoa Style for Objective-C: Part II》http://cocoadevcentral.com/articles/000083.php
[6] 《objective-c-conventionsI》https://github.com/github/objective-c-conventions
[7] 《The official raywenderlich.com Objective-C style guide.》https://github.com/raywenderlich/objective-c-style-guide#cgrect-functions
[8] 《Blocks or Delegation》http://stablekernel.com/blog/blocks-or-delegation/
文档修订历史
时间 |
备注 |
2015-10-18 |
添加code-snippet示例 |
2014-01-16 |
完善代理、条件语句、单例 |
2013-09-07 |
编写高质量的Objective-C代码 |
如果喜欢此文,记得点击文章下方的推荐,以让更多的人有所收获。
文章中如有错误或不当之处望不吝指出,谢谢!
我的邮箱和微博: xdreamarshal@gmail.com, http://weibo.com/xdream86
本文的pdf下载地址。