命名规范

iOS开发者规范:以苹果开发者中心规范为标准(Coding Guidelines for Cocoa),以此为标准添加部分规范.

iOS命名两大原则是:可读性高和防止命名冲突(通过加前缀来保证). Objective-C 的命名通常都比较长, 名称遵循驼峰式命名法. 一个好的命名标准很简单, 就是做到在开发者一看到名字时, 就能够懂得它的含义和使用方法. 另外, 每个模块都要加上自己的前缀, 前缀在编程接口中非常重要, 可以区分软件的功能范畴并防止不同文件或者类之间命名发生冲突, 比如相册模块(PhotoGallery)的代码都以PG作为前缀: PGAlbumViewController, PGDataManager.

命名

命名规则对于维护代码来说是非常重要的,。Objective-C方法名往往很长,不过这也有好处,方法即注释。

命名规则采用驼峰法:除第一个单词之外,其他单词首字母大写。

基本原则

1. 清晰

又清晰又简洁是最好的了,但简洁不如清晰重要。总的讲不要使用单词的简写,除了非常常用的简写以外,尽量使用单词全称。

API的名称不要有歧义,一看你的API就知道是以什么方式做了什么事情,不要让人有疑问

2. 一致性

做某个事情代码通常都叫这个名字,比如tag、setStringValue,那么你也这么叫。

你在不确定怎么起名字的时候,可以参考一些常用的名字:Method Arguments

类命名

类名(不包括类别和协议名)应该用大写开头的大驼峰命名法。类名中应该包含一个或多个名词来说明这个类(或者类的对象)是做什么的。

在应用级别的代码里,尽量不要使用带前缀的类名。每个类都有相同的前缀不能提高可读性。

不过如果是编写多个应用间的共享代码,前缀就是可接受并推荐的做法了(型如 JKPhotoBrowser ).如

@interface ImageBrowseView :UIView

@end

@interface JKPhotoBrowser :UIView

@end

类别命名

类名+标识+扩展(UIImageView +HP+Web)

例:如果我们想要创建一个基于UIImageView 的类别用于网络请求图片,我们应该把类别放到名字是UIImageView+HPWeb.h的文件里。UIImageView为要扩展的类名,HP为专属标识,Web为扩展的功能。

类别的方法应该都使用一个前缀(型如hp_myCategoryMethodOnAString ),以防止Objective-
C代码在单名空间里冲突。如果代码本来就不考虑共享或在不同的地址空间(address-space),方法命名规则就没必要恪守了。

类别HPWeb头文件,UIImageView+HPWeb.h如下:

@interface UIImageView (HPWeb)
(void)hp_setImageWithURLString:(NSString *)urlStr;
@end

协议(委托/代理)命名

与类命名相同,此外需添加“Delegate”后缀

举例:ReplyViewDelegate

方法命名

1.首字母小写,之后每个单词首字母都大写

2.方法名使用动词短语

举例:- (void)setPostValue:(int)value

方法参数命名

1.首字母小写,之后每个单词首字母都大写
2.具有足够的说明性
3.不需要添加类型前缀

举例:- (void)sendUserInfo:(NSDictionary *)userInfo

方法命名

方法使用小驼峰法命名, 一个规范的方法读起来应该像一句完整的话,读过之后便知函数的作用。执行性的方法应该以动词开头,小写字母开头,返回性的方法应该以返回的内容开头,但之前不要加get。
如:

- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;

(instancetype)arrayWithArray:(NSArray *)array;

如果有参数,函数名应该作为第一个参数的提示信息,若有多个参数,在参数前也应该有提示信息(一般不必加and)

一些经典的操作应该使用约定的动词,如initWith,insert,remove,replace,add等等。

变量命名

变量名使用小驼峰法, 使变量名尽量可以推测其用途属性具有描述性。别一心想着少打几个字母,让你的代码可以迅速被理解更加重要。

1. 类成员变量:

类中所有成员变量以属性的方式提供,不要使用其他类型的变量声明
示例:

@interface ViewController ()

@property (nonatomic,strong)NSMutableArray *dataArray;

@property (nonatomic,strong)UITableView *tableView;

@end


@implementation ViewController

@end

2. 一般变量命名

示例:

NSMutableArray *ticketsArray = [NSMutableArrayarrayWithCapacity:0];

NSInteger numCompletedConnections =3;

3. 常量命名

常量(预定义,枚举,局部常量等)使用小写k开头的驼峰法,比如kInvalidHandle ,kWritePerm
示例:

#define kRunAnnotationStartPointTitle @"起点"

枚举请使用oc风格,不要使用C语言风格

typedef NS_ENUM (NSInteger,RunGoalTypeE){

 kRunGoalTypeNone = 0, //无目标

 kRunGoalTypeTime = 1, //以时间为目标

 kRunGoalTypeDistance = 2, //以距离为目标

 kRunGoalTypeCalori = 3, //以消耗卡路里为目标

};

字符串常量使用const修饰

NSString *const kGroupInfoName =@"name";

图片资源文件命名

如果设计人员提供的图片不复合规范,请开发人员让相关人员进行修改再使用。UI设计规范。
先看下新浪微博app图片资源命名方式,下面是部分截图

图标命名1.png

图片命名2.png

以下为相关要求:
图片资源命名方式,以功能为组织形式,是一个很好的习惯,有利于查看资源文件。

原则:

  1. 采用单词全拼,或者大家公认无岐义的缩写(比如:nav,bg,btn等)
  2. 采用“模块+功能”命名法,模块分为公共模块、私有模块。公共模块主要包括统一的背景,导航条,标签,公共的按钮背景,公共的默认图等等;私有模块主要根据app的业务
  3. 功能模块划分,比如用户中心,消息中心等

备注:建议背景图采用以bg作前缀,按钮背景采用btn作前缀(不作强制要求,项目实际负责人根据团队特点确定即可)

公共模块命名示例:

导航条背影图片:bg_nav_bar@2x.png

导航返回按钮:bg_nav_back_normal@2x.png
bg_nav_back_selected@2x.png

标签item背景:bg_tabbar_record_normal@2x.pngbg_tabbar_record_selected@2x.png

私有模块命名示例:

以Joggers APP的用户中心图片资源为例说明,
uc——user center+

用户中心头像默认图:bg_uc_avatar@2x.png

用户中心顶部默认背景图:bg_uc_top_defaut@2x.png

用户中心底部背景图:bg_uc_bottom@2x.png

这部分工作较为繁杂,并且在程序员心中会认为是技术含量较低的一个工作,但图片命名的严谨性同样会反映出我们对细节的追求,细节决定成败。

补充规范

1. 删除多余的空行

所有方法与方法之间空1行

所有代码块之间空1行

2. 删除多余的注释

删除注释掉的代码

删除没有意义的注释

3. 删除多余的方法

如果方法没有使用到,请删除它

如果方法没有执行任何业务逻辑,请删除它或者给出一定注释

4. 删除未被使用的资源文件

5. 添加必要的注释

所有 .h 文件中的property 需要给出注释

所有自定义的方法需要给出注释

比较大的代码块需要给出注释

所有代码中出现的阿拉伯数字需要给出注释

程序中出现加密/解密 逻辑的操作地方,需要给出注释说明过程(无论是系统还是自定义)

6. 整体代码风格需要统一

代码后面的”{“ 不需要单独占用一行

逻辑运算符 与 代码之前空一格

“#pragma mark -” 与下面的代码之前不要空行

遵循一般性的代码规范

7.命名规范

所有类名称以项目工程开头命名,eg:“XP”、“ZJG”、“SZ”

针对不同视图控制器,在末尾添加后缀,eg:

UIViewController 后缀添加“ViewController”

UIView 后缀添加“View”

UIButton 后缀添加“Button"

UILabel 后缀添加“Label"

8.代码量控制

单页代码最好控制在800行以内,每个方法最好不要超过80行,过多建议对代码进行重构

9.及时更新代码风格

对其他项目中copy过来的代码,根据具体需要更新代码风格,及时删除未被使用的代码

10. 及时新建目录

项目中所有Group都需要在项目目录中存在一个真实的目录,Group中的文件与真实目录中文件一一对应。

11. VC等类中的代码规范

视图控制器中相关代码的位置,按图中的位置摆放

类中方法位置规范.png

代码示例

1.判断nil或者YES/NO

Preferred:

 if (someObject) { ... }

 if (!someObject) { ... }

Not preferred:

if (someObject == YES) { ...}

if (someObject != nil) { ...}

2. 条件赋值

Preferred:

result = object ? : [self createObject];
Not preferred:

result = object ? object : [self createObject];

3.初始化方法

Preferred:

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve"];

NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal"};

NSNumber *shouldUseLiterals = @YES;

NSNumber *buildingZIPCode = @10018;

4. 定义属性

Preferred:

@property (nonatomic, readwrite, copy) NSString *name;

1.建议定义属性的时候把所有的参数写全, 尤其是如果想定义成只读的(防止外面修改)那一定要加上readonly, 这也是代码安全性的一个习惯.

2.如果是内部使用的属性, 那么就定义成私有的属性(定义到.m的class extension里面)

3.对于拥有Mutable子类型的对象(e.g. NSString, NSArray, NSDictionary)一定要定义成copy属性. Why? 示例: NSArray的array = NSMutableArray的mArray; 如果mArray在某个地方改变了, 那array也会跟着改变.

4.尽量不要暴露mutable类型的对象在public interface, 建议在.h定义一个Inmutable类型的属性, 然后在.m的get函数里面返回一个内部定义的mutable变量.

5. BOOL赋值

Preferred:

BOOL isAdult = age > 18;

Not preferred:

BOOL isAdult;

if (age > 18) {

 isAdult = YES;

} else {

 isAdult = NO;

}

6. 不要使用Magic numberPreferred:

if (car == Car.Nissan)

or

const int adultAge = 18;

if (age > adultAge) {

 ...

}

Not preferred:

if (carName == "Nissan")

or

if (age > 18) { ... }

7.复杂的条件判断

Preferred:

if ([self canDeleteJob:job]) { ... }

- (BOOL)canDeleteJob:(Job *)job {

 BOOL invalidJobState = job.JobState == JobState.New

 || job.JobState == JobState.Submitted

 || job.JobState == JobState.Expired;


 BOOL invalidJob = job.JobTitle && job.JobTitle.length;

 return invalidJobState || invalidJob;

}

Not preferred:

if (job.JobState == JobState.New

 ||job.JobState == JobState.Submitted

 || job.JobState == JobState.Expired

 || (job.JobTitle && job.JobTitle.length)) {

 //....

}

清晰明了, 每个函数DO ONE THING!

8.嵌套判断

Preferred:

if (!user.UserName) return NO;

if (!user.Password) return NO;

if (!user.Email) return NO;

return YES;

Not preferred:

BOOL isValid = NO;

if (user.UserName) {

 if (user.Password) {

 if (user.Email) isValid = YES;

 }

}

return isValid;

9. 参数过多

Preferred:

- (void)registerUser(User *user) { // to do... }

Not preferred:

- (void)registerUserName:(NSString *)userName

 password:(NSString *)password

 email:(NSString *)email {

 // to do...

}

当发现实现某一功能需要传递的参数太多时, 就预示着你应该聚合成一个model类了...这样代码更整洁, 也不容易因为参数太多导致出错

10. 回调方法

Preferred:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

函数调用的可知性, 回调时被调用者要知道其调用者, 方便信息的传递, 所以建议在回调方法中第一个参数中加上调用者

参考文章:iOS 编程规范-ZSQ


☟☟可点击下方广告支持一下☟☟

最后修改:2017 年 02 月 15 日
请我喝杯可乐,请随意打赏: ☞已打赏列表