iOS代码规范

方法声明与定义:

1.星号前统一要求需要输入空格

2.方法体左大括号于方法名的右侧

3.-或者+与返回类型之间需要有空格。参数列表中,只有参数之间有空格。

- (void)doSomethingWithString:(NSString *)theString {

...

}

如果一行有非常多的参数,更好的方式是将每个参数单独拆成一行。如果使用多行,将每个参数前的冒号对齐。

- (void)doSomethingWith:(GTMFoo *)theFoo

rect:(NSRect)theRect

interval:(float)theInterval {

...

}

协议:

尖括号所包括的协议名称与前面的类型标识之间不应该有空格

@interface MyProtocoledClass : NSObject {

@private id delegate;

}

方法名:

方法名应该读起来就像句子,这表示你应该选择与方法名连在一起读起来通顺的参数名。

convertPoint:fromRect:

replaceCharactersInRange:withString:

访问器方法应该与他们getting的的成员变量的名字一样,但不应该以get作为前缀。

例如:

- (id)getDelegate;  // AVOID

- (id)delegate;     // GOOD

变量名:

要为变量起一个描述性的名字。不要担心浪费列宽,若包含两个以上单词的命名应该使用驼峰命名方式,因为让新的代码阅读者立即理解你的代码更重要。

错误的命名:

int w;

int nerr;

int nCompConns;

UIButton*settingsButton;

tix = [[NSMutableArray alloc] init];

obj = [someObject object];

p = [network port];

正确的命名:

int numErrors;

int numCompletedConnections;

tickets = [[NSMutableArray alloc] init];

userInfo = [someObject object];

port = [network port];

星号应紧贴变量名称表示指向变量的指针,比如:

正确用法:

NSString *text;

不当用法:

NSString* text;

NSString * text;

方法调用:

方法调用时,所有参数应该在同一行

[myObject doFooWith:arg1 name:arg2 error:arg3];

或者每行一个参数,以冒号对齐

[myObject doFooWith:arg1

name:arg2

error:arg3];

[UIViewanimateWithDuration:1.0

animations:^{

// something

}

completion:^(BOOL finished) {

// something

}];

异常:

每个@标签应该有独立的一行,在@与{}之间需要有一个空格。@catch与被捕捉到的异常对象的声明之间也要有一个空格。

@try {

foo();

}

@catch (NSException *ex) {

bar(ex);

}

@finally {

baz();

}

条件语句的编写:

1.为避免错误,条件语句体必须使用大括号,即便语句体中的语句可以不必使用大括号(比如只有一行语句)。常见的错误包括在不使用大括号的情况下添加第二行语句,以为它属于if语句的一部分。此外,更可怕的事情是,如果条件语句中的代码行被注释,则本不术语条件语句的下一行代码将变成条件语句的一部分。此外,这种编码风格和所有其它条件语句均保持一致.

例如:

恰当用法:

if(!error) {

returnsuccess;

}

不当用法:

if(!error)

returnsuccess;

不当用法2:

if(!error)returnsuccess;

2. 编写括号内的判断语句时,为避免手误演变成赋值操作,一般将常量或nil放置在左边

例如:

if(nil == self.dataList) {

}

if(0 == theCount) {

}

Case语句

除非编译器强制要求,括号在 case 语句里面是不必要的。但是当一个 case 包含了多行语句的时候,需要加上括号。

switch (condition) {

case 1:

// ...

break;

case 2: {

// ...

// Multi-line example using braces

break;

}

case 3:

// ...

break;

default:

// ...

break;

}

有时候可以使用 fall-through 在不同的 case 里面执行同一段代码。一个 fall-through  是指移除 case 语句的 “break” 然后让下面的 case 继续执行。

switch (condition) {

case 1:

case 2:

// code executed for values 1 and 2

break;

default:

// ...

break;

}

常量

相对字符串字面量或数字,我们更推荐适用常量。应使用static方式声明常量,而非使用#define的方式来定义宏。

例如:

恰当用法:

static NSString * const NYTAboutViewControllerCompanyName =@"The New York Times Company";

static const CGFloat NYTImageThumbnailHeight =50.0;

不当用法:

#define CompanyName @"The New York Times Company"

#define thumbnailHeight 2

枚举类型

在使用enum的时候,推荐适用最新的fixed underlying type(WWDC 2012 session 405- Modern Objective-C)规范,因为它具备更强的类型检查和代码完成功。

例如:

typedefNS_ENUM(NSInteger, NYTAdRequestState) {

NYTAdRequestStateInactive,

NYTAdRequestStateLoading

};

布尔变量

因为nil将被解析为NO,因此没有必要在条件语句中进行比较。永远不要将任何东西和YES进行直接比较,因为YES被定义为1,而一个BOOL变量可以有8个字节。

例如:

恰当用法:

if(!someObject) {

}

不当用法:

if(someObject==nil) {

}

以下是BOOL变量的使用:

恰当用法:

if(isAwesome)

if(![someObject boolValue])

不当用法:

if([someObject boolValue]==NO)

if(isAwesome==YES)// Never do this.

三目运算

仅当使用该运算子可以让代码显得更清晰易懂时方可使用三元运算子,切三目运算体内应均为运算结果,不然被忽略的错误比较容易产生。 更多情况下应使用条件语句。使用类似if的条件语句对多种条件进行判断通常要更容易理解,或使用实例变量。

恰当用法:

result=a>b?x:y;

不当用法:

result=a>b?x=c>d?c:d:y;

CGRect函数

当需要获取一个CGRect矩形的x,y,width,height属性时,应使用CGGeometry函数,而非直接访问结构体成员。

例如:

恰当用法:

CGRect frame=self.view.frame;

CGFloat x=CGRectGetMinX(frame);

CGFloat y=CGRectGetMinY(frame);

CGFloat width=CGRectGetWidth(frame);

CGFloat height=CGRectGetHeight(frame);

不当用法:

CGRect frame=self.view.frame;

CGFloat x=frame.origin.x;

CGFloat y=frame.origin.y;

CGFloat width=frame.size.width;

CGFloat height=frame.size.height;

单例

在创建单例对象的共享实例时,应使用线程安全模式,获取单例对象类方法命名使用sharedXXXX。

例如:

(instancetype)sharedInstance{

staticidsharedInstance =nil;

staticdispatch_once_tonceToken;

dispatch_once(&onceToken, ^{

sharedInstance = [[self alloc] init];

});

return sharedInstance;

}

美化代码:

空格

方法的大括号和其他的大括号(if/else/switch/while 等) 总是在同一行开始,在新起一行结束。

推荐:

if (user.isHappy) {

//Do something

}

else {

//Do something else

}

不推荐:

if (user.isHappy)

{

//Do something

} else {

//Do something else

}

换行

self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];

一个像上面的长行的代码在第二行以一个间隔(2个空格)延续

self.productsRequest = [[SKProductsRequest alloc]

initWithProductIdentifiers:productIdentifiers];

利用代码块

一个 GCC 非常模糊的特性,以及 Clang 也有的特性是,代码块如果在闭合的圆括号内的话,会返回最后语句的值

NSURL *url = ({

NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint];

[NSURL URLWithString:urlString];

});

所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染。

Pragma Mark

#pragma mark - 是一个在类内部组织代码并且帮助你分组方法实现的好办法。 我们建议使用 #pragma mark - 来分离:

#pragma mark - View Lifecycle (View 的生命周期)

- (void)viewDidLoad { /* ... */ }

- (void)viewWillAppear:(BOOL)animated { /* ... */ }

- (void)didReceiveMemoryWarning { /* ... */ }

#pragma mark - Custom Accessors (自定义访问器)

- (void)setCustomProperty:(id)value { /* ... */ }

- (id)customProperty { /* ... */ }

建立委托者和数据源使用“weak关键字”

@property (nonatomic, weak) id delegate;

@property (nonatomic, weak) id dataSource;

默认情况下,委托对象需要实现 protocol 的方法。可以用@required 和 @optional 关键字来标记方法是否是必要的还是可选的。

@protocol ZOCSignUpViewControllerDelegate 

@required

- (void)signUpViewController:(ZOCSignUpViewController *)controller didProvideSignUpInfo:(NSDictionary *);

@optional

- (void)signUpViewControllerDidPressSignUpButton:(ZOCSignUpViewController *)controller;

@end

对于可选的方法,委托者必须在发送消息前检查委托是否确实实现了特定的方法(否则会 crash):

if ([self.delegate respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) {

[self.delegate signUpViewControllerDidPressSignUpButton:self];

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • iOS编程规范0规范 0.1前言 为􏰀高产品代码质量,指导广大软件开发人员编写出简洁、可维护、可靠、可 测试、高效...
    iOS行者阅读 4,446评论 21 35
  • 代码规范 1. h文件代码 类功能说明注释。属性说明注释。方法说明注释。类名加前缀,避免命名空间冲突. 2. m文...
    ValienZh阅读 1,394评论 0 2
  • 对于我而言,为数不多取悦自己的方式就是,发现一片新的大陆,或者将自己的屋子收拾成自己想要的样子。 controll...
    senpaiLi阅读 242评论 1 1
  • 一、命名规范 1、统一要求含义清楚,尽量做到不需要注释也能了解其作用,若做不到,就加注释,使用全称,不使用缩写。 ...
    Untils阅读 552评论 0 0
  • 芥末烤贝壳/原创 亲爱的,我会在未来遇到你,并且爱上你,我们会许下度过一生的承诺,从此执子之手与子偕老。 ——引子...
    芥末烤贝壳阅读 401评论 0 0