iOS代码书写规范

//////////////////////////////////////////////////////////////////////
/**** 1.宏定义 ****/
说明: 宏定义在c/c++开发过程中, 能够起到简化代码, 控制代码执行, 注释, 消除警告/开启警告, 消除IDE提示错误等功能, 如非必要, 开发过程中, 应谨慎使用
另外: 宏定义一定要写于文件的开头, 如果想被外部使用, 则置于头文件, 如果仅仅本类使用则置于实现文件

<1>与Cocoa Touch相关的核心基础库相关, 用于全局代码层次上的宏定义
使用核心基础库的前缀, 采用驼峰命名法, 并且宏定义应简洁明了, 如颜色宏

define UIColorRGB(red, green, blue) [UIColor colorWithRed:(red) green:(green) blue:(blue) alpha:1.0f]

<2>单独文件使用的宏定义同样采用驼峰命名法, 但是要在前面添加’k’例如 布局UI时, 想定义一个间距为20

define kLayoutMargin 20

功能: 便于修改, 避免代码写死, 修改起来还要找到固定的代码行

<3>如果想利用宏定义控制某些环境变量, 或者开关之类, 使用_命名法, 并且首个单词必须交代清楚作用(可用大家都能懂的缩写)
如: 测试环境 #define ENV_DEVELOPMENT 1 生产环境 #define ENV_DISTRIBUTION 1

<4>功能类宏定义
功能1: 字符串宏定义 #define STR_Search @“搜索”
功能2: 图标类宏定义 #define ICON_Search @“search.png”
功能3: 字典key值宏定义 #define KEY_Anyone @“anyone”
功能4: 网络请求URL宏定义 #define URL_GetUserList @“http://10.110.20.23:80/getUserList/index.html
功能5: 单例类宏定义 #define SINGLTON_User [User defaultUser]
//////////////////////////////////////////////////////////////////////

/**** 2.全局变量 ****/
说明: 全局变量在oc/c++开发中, 同样有着至关重要的作用, 但是oc可以使用单例类来实现全局变量的作用, 但也不免排除有些开发者直接使用全局变量

注意:
<1>.命名规则: 使用驼峰命名法, 前缀为XM, 第一个单词简要的具体说明性质
例如: BOOL型全局变量为进入后台 BOOL XMEnterBackground = NO;
例如: 通知名称 NSString *XMNotificationReceiveAddressbookRefresh = @“XMNotificationReceiveAddressbookRefresh”;
<2>.所有全局变量的初始化, 应放于实现文件, 如果使用的话, 可以在其头文件利用extern 函数, 例如: extern NSString *XMNotificationReceiveAddressbookRefresh;
<3>.当然开发人员也可以使用其他修饰词, 如果你不想改变全局变量的值则可以 extern const NSString *XMNotificationReceiveAddressbookRefresh;
//////////////////////////////////////////////////////////////////////

/**** 3.文件命名规则 ****/
说明: 文件的命名规则也同样重要, 除category以外, 有所的文件命名应为 前缀 XMxxxx.h XMxxxx.m XMxxxx.xib
注意:
<1>.使用xib时吗xib的文件名要头文件, 实现文件一样
<2>.文件的命名规则, 也应遵守驼峰命名法, 并且第一个单词尽量简单明了说明类的作用是什么
例如:通讯录控制器 XMAddressbookViewController.h
菜单视图 XMMenuView.h
联系人模型 XMContactModel.h
<3>.所创建类头文件, 应将作者信息, 创建时间, 最近修改, 主要功能填写清楚
<4>.个人封装的视图, 切忌与其他的文件耦合性太高, 应尽量注重代码可移植性, 代码可重用性, 代码可维护性等多方面考虑, 如何封装
模板:
//
// XMDetailConferenceViewController.h
// 功能: 会议详情页的展示功能 (控制器)
// 作者: xx
// 创建日期: 2015-12-27
// 最近修改: 2016-10-13
//

//////////////////////////////////////////////////////////////////////

/**** 4.图片资源命名规则 ****/
说明: 开发人员可能会根据UI视觉设计布局页面, 有些页面需要使用大量的切图, 而图片的命名, 也同样要有规范
注意:
<1>.公用图片要根据用途命名, 但要注意区分不同的状态 (普通: normal 高亮: highlight 选中: selected), 命名格式icon_xxxxx(用途)_xxxx(区分)_normal(状态).png
例如:
tab页签的图片: icon_tabbar_addressbook_normal@2x.png icon_tabbar_addressbook_selected@2x.png icon_tabbar_addressbook_highlight@2x.png
导航返回的图片:icon_navgationBar_back_normal@2x.png icon_navgationBar_back_selected@2x.png icon_navgationBar_back_highlight@2x.png
<2>.非公用图片, 命名格式xxxx(控制器/视图名)_xxxxx(用途)_xxxx(区分)_normal(状态).png
例如: 通讯录控制器, 搜索按钮: addressbook_btn_search_normal@2x.png
命名规则前缀英文或者拼音不做限制, 应简洁明了, 通俗易懂, 例如icon_erweima.png(二维码) 都可以
//////////////////////////////////////////////////////////////////////

/**** 5.重定义枚举类型书写规范 ****/
说明: 在发开过程中, 某些类需要支持不通的属性, 例如, 一个会议详情页面, 需要根据model的不同, 从而展示不通的提示
如果用int 0, 1, 2也可以, 但是不好区分, 也不好维护, 那么定义枚举就能很方便的阅读代码

注意: 定义枚举, 枚举的前缀一定是 你重定义的别名 例如XMDetailConferenceType+xxx, 如下
typedef enum : NSUInteger {
XMDetailConferenceTypeOnMeeting,
XMDetailConferenceTypeWillBegin,
XMDetailConferenceTypeEnd,
} XMDetailConferenceType;
//////////////////////////////////////////////////////////////////////

/**** 6.代码书写规范 ****/
说明: 开发人员有个良好的代码书写规范, 对维护代码有着重要的意义


<1>.成员变量书写规范
成员变量, 分为三种类型 @private @public @protected, 开发人员可酌情使用修饰词, 成员变量应如下做出注释
注意: 成员变量一定要写成 _xxx 格式, for大家的良好编码习惯, 模仿苹果工程师才是正确的选择

例如:
@interface NSThread : NSObject {
@private
id _private; //私有
uint8_t _bytes[44]; //字节数
}



<2>.属性书写规范
通常属性应置于成员变量之下, 方法之上的位置, 开发人员可酌情使用属性修饰词, 但是注意ARC工程的属性修饰词应尽量使用strong或者weak, 属性也要明确的注释
注意: 为了代码美观, 开发人员尽量将其对其(不强制), 驼峰命名法, 简洁明了
例如:
//菜单颜色

@property (nonatomic, strong) UIColor       *menuColor; 

//代理

@property (nonatomic, weak)   id<LYMenuViewDelegate> delegate;    

或者
/菜单颜色/

@property (nonatomic, strong) UIColor       *menuColor; 

/代理/

@property (nonatomic, weak)   id<LYMenuViewDelegate> delegate;    



<3>.方法书写规范
方法书写规范也应当简单明了, 英文与拼音不做要求限制, 驼峰命名法
动态方法 书写规范:- (返回值)方法名:(参数类型)形参 方法名:(参数类型)形参{

    }

静态方法 书写规范:+ (返回值)方法名:(参数类型)形参 方法名:(参数类型)形参{

    }

方法体内, 至少方法和方法体内间隔空一行
以表格视图为例

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

//编写方法体, 方法体与方法名需空一行
return 1;
}



<4>.条件语句书写规范
条件语句即所谓的if else, switch case, 书写这类语句时, 注意对其方式, 以及大括号位置

特别注意: 在这里切记将大括号至于if语句下面, 因为如果代码行数较多的情况下, 条件语句嵌套使用, 开发人员很难找到对应的条件语句大括号, 而且嵌套使用, 应该错位, 见2的操作

  1. 当判断一个变量为简单类型数据时, 例如判断a = 1
    规范为 if (1 == a){ 一定要把简单数据类型放在左边, 因为假如你少写了=, 条件语句即为赋值语句, 条件总是为真, 则会引发预想不到的后果, 但是将一个变量赋给一个简单类型的数字, IED会提示错误

//to do
}

  1. switch(a){
    case: 1{ 如果switch嵌套条件语句, 则
    if (YES){
    // to do
    }
    }
    break;

    case: 2 如果不嵌套, 随意使用
    break;

    default: 注意default可以省略, 如果case在配和枚举使用考虑完全的话
    break;
    }



<5>.控制流书写规范
控制流即为循环语句 while, for, forin, do-while
注意书写格式, 任然是大括号的问题, 推荐以下写法

例如:
int a = 0;
while(a < 10){

//至少与控制流语句空一行
a++;
}
例如:
int a = 0;
do{

//至少与控制流语句空一行
a++;
}while(a < 10);

注意:无论for还是while开发人员应该特别注意循环条件, 避免循环一直执行



<6>.协议书写规范
首先: 协议的命名, 如果在本类中应命名为 xxxx(类名)Delegate, 例如: @protorl XMMenuViewDelegate <NSObject>
开项目开发过程中, 协议必然会用到, 代理设计模式有着很大的用途, 例如: 回调方法, 反向传值, 解耦等等

注意: 协议方法如果写的过于简单的话, 开发人员容易将其认为是本类的方法, 为了便于区分, 建议大家沿着苹果工程师的规范书写协议方法, 协议的功能应当给出注释, 英/中文不限
例如: - (返回值)类:(本类型)本类参数 方法名:(类型)形参;
@protocol LYMenuViewDelegate <NSObject>
@required
//protocol must be implementation

  • (void)menuView:(LYMenuView *)view tableView:(UITableView *)tableView didSelectedRowAtIndexPath:(NSIndexPath *)indexPath dataSource:(LYMenuViewDataSource *)dataSource;
    @end

这点上模仿苹果, 如表格视图的代理方法:

  • (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;


<7>.空行规范
说明: 在书写代码的时候, 空行规范也是一定要有
例如: 算数表达式 a = b + c;
格式: a(空行)=(空行)b(空行)+(空行)c;

例如: 定义变量: int a = 10;

例如: 书写方法时, 空行规范
格式: -(空行)(返回值)类:(类型)本类参数(空行)方法名:(类型)形参;
如果类型为一直对象, 那么 类型 即可 拆分为 类名+(空行)+(*)
即: - (void)tableView:(UITableView *)tableView;


//////////////////////////////////////////////////////////////////////

/**** 7.方法书写需要注意的事项 ****/
说明: 如果方法所占用的代码行数超过200行, 开发人员就要想办法, 将其方法从大括号里分离出几个简单的方法, 嵌套方法使用, 避免方法体太多, 导致看其代码眼花缭乱

举个例子

  • (void)testLargeMethod{

    int state = [User getState];
    if (1 == state) {

    for(id object in _array1){
    NSLog(@“%@”, object);
    }

    }else if (2 == state) {

    for(id object in _array2){
    NSLog(@“%@”, object);
    }

    }else if (3 == state) {

    for(id object in _array3){
    NSLog(@“%@”, object);
    }

    }else if (4 == state) {

    for(id object in _array4){
    NSLog(@“%@”, object);
    }

    }else if (5 == state) {

    for(id object in _array5){
    NSLog(@“%@”, object);
    }

    }
    }
    这样看起来很繁琐的代码, 而且又有赘余的代码, 则完全可以拆分
    例如:

  • (void)testLargeMethod{

    int state = [User getState];
    NSArray *temp = nil;

    if (1 == state) {
    temp = _array1;
    }else if (2 == state) {
    temp = _array2;
    }else if (3 == state) {
    temp = _array3;
    }else if (4 == state) {
    temp = _array4;
    }else if (5 == state) {
    temp = _array5;
    }

    [self printObjectFromArray:temp];
    }

  • (void)printObjectFromArray:(NSArray *)array{
    for(id object in _array1){
    NSLog(@“%@”, object);
    }
    }
    //////////////////////////////////////////////////////////////////////

/**** 8.编码格式 ****/
说明: 编码格式对于提高阅读代码效率, 快速理清代码思路有着很大帮助, 开发人员应考虑除自己阅读以为, 其他同事还有可能阅读你的代码, 从而考虑, 从代码思想上, 代码层次, 以及代码质量上严格要求自己

举个例子, 一段编码习惯良好的代码, 阅读起来非常方便

@prmga mark - 测试方法

  • (void)testMethod{

    //获取状态
    int state = [User getState];

    if (1 == state) { 为了便于阅读, 每个方法完毕, 空一行
    temp = _array1;
    }else if (2 == state) {
    temp = _array2;
    }else if (3 == state) {
    temp = _array3;
    }else if (4 == state) {
    temp = _array4;
    }else if (5 == state) {
    temp = _array5;
    }

    //遍历数组的结果 适当的添加注释, 使得开发就是那么的简单 -_-
    [self printObjectFromArray:temp];
    }
    //////////////////////////////////////////////////////////////////////

/**** 9.不寻常的引用问题 ****/

举个例子: 大家都注意下, block很容易引发循环引用问题

@property (nonatomic, copy) void(^objBlock)(id obj);

  • (void)test{
    NSLog(@"%s", func);
    }

  • (void)implementBlock{
    错误的写法: 导致循环引用
    self.objBlock = ^void(id obj){ 第一种写法 此种写法分析: self持有block, block体内部又对self增加了一个引用, 形成引用闭环, 即所谓的循环引用

      [self test];
    

    };

                              正确的写法, 不会导致循环引用
    

    __weak Model *wself = self; 第二种写法 此种写法不会对self持有引用, 因为__weak的实现:
    self.objBlock = ^void(id obj){ weak表示的是一个弱引用,这个引用不会增加对象的引用计数,并且在所指向的对象被释放之后,weak指针会被设置的为nil
    具体原理很复杂, 不在此分析, 只是提醒注意下
    __strong Model *sself = wself;
    [sself test];

    };

}
//////////////////////////////////////////////////////////////////////

/**** 10.代码优化 ****/
说明: 开发过程中, 我们接受的模块可能是其他人新写的, 也可能是年头比较陈旧的老代码, 如果阅读起来很困难
建议:
<1>.某块方法代码赘余, 或者实现方式有点繁琐, 思路不清晰, 有可能引发问题的代码, 开发人员可以在排期时间内, 将此代码优化的时间也一起添加进去.
<2>.某个类总体实现思路有问题, 或者以上等等, 在不影响项目该模块的功能和排期的情况下, 建议重写模块, 重构逻辑, 重构中, 优化代码
//////////////////////////////////////////////////////////////////////

/**** 11.代码注释规范 ****/
说明: 凡是创建的文件, 头文件暴露出来的方法都需要添加注释, 无论简单与否, 实现文件, 每个方法也应有注释, 必要的代码逻辑也需要注释
<1>.创建头文件注释规范, 详细见 //3.文件命名规则
<2>.属性, 成员变量注释, 详细见 //6.代码书写规范
<3>.方法注释, 例如

方式1:
/**

  • 实现block
  • @param arg 所传递的参数
    */
  • (void)implementBlock:(id)arg{

    //弱引用
    __weak Model *wself = self;
    self.objBlock = ^void(id obj){

    //强引用
    __strong Model *sself = wself;
    [sself test];

    };

}

方式2:
@pragm mark - 实现block

  • (void)implementBlock:(id)arg{

    //弱引用
    __weak Model *wself = self;
    self.objBlock = ^void(id obj){

    //强引用
    __strong Model *sself = wself;
    [sself test];

    };

}

方式三:
// 实现block

  • (void)implementBlock:(id)arg{

    __weak Model *wself = self; //弱引用
    self.objBlock = ^void(id obj){

      __strong Model *sself = wself;  //强引用
      [sself test];
    

    };

}
方法注释多样保证对齐, 明显, 言简意赅, 中英文不做限制, 但为了保证其他人能看懂, 应尽量使用中文注释
//////////////////////////////////////////////////////////////////////

/**** 12.有关于代码重用 ****/
以工程中的相关代码举例.
类似XMSearchGroupProtraitView自定义试图.在群组列表以及最近通讯cell中使用到.但是此控件却仅是XMSearchGroupCell类中声明的全局变量.类似此类多出使用到的控件,请在CustomView文件分类中单独写出一个类来使用.因为在最近通讯cell中使用的仅是一个XMSearchGroupProtraitView控件而不是一个cell.
单独仅用一次的控件、对象可以在你自己类中单独去写,工程中统一用到的一定要统一起来.
//////////////////////////////////////////////////////////////////////

/**** 13.有关于资源文件的存放 ****/
1、例如图片资源文件,首先在最新的recourse文件夹中寻找你需要添加图片的分类,然后再去添加图片.
2、第三方库文件,第三方库相关文件资源统一在ThirdPart<第三方框架>文件夹中存放
3、所有创建的新类、在本地文件夹中的层级关系要与工程中的一致

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

推荐阅读更多精彩内容

  • iOS编程规范0规范 0.1前言 为􏰀高产品代码质量,指导广大软件开发人员编写出简洁、可维护、可靠、可 测试、高效...
    iOS行者阅读 4,446评论 21 35
  • 前言 关于代码规范的重要性这里不做过多解释,能看到这篇文章说明你已经开始重视代码规范了(代码规范看起来是在限制你的...
    iOS鑫阅读 982评论 1 10
  • 转自:船长_iOS开发公众号 1.精简代码, 返回最后一句的值,这个方法有一个优点,所有的变量都在代码块中,也就是...
    smm987阅读 289评论 0 0
  • 一、前言 本规范基于Google Objective-C Style Guide,对其中的说明性语句及非ARC部分...
    IIronMan阅读 870评论 0 6
  • 代码格式 使用空格而不是制表符 Tab 不要在工程里使用 Tab 键,使用空格来进行缩进。在 Xcode > Pr...
    small_Sun阅读 1,355评论 1 3