一、排版规范
1.代码结构
一个完整的iOS工程代码结果如下:
</pre><pre name="code" class="objc">Project
|- PublicModule 这个目录存放公共模块文件,不同项目工程公用同一套,原则上不对其中文件进行修改。
|- Models 这个目录存放一些与数据相关的Model文件
|- Macro 这个目录存放了整个应用会用到的宏定义,公共模块已定义的除外
|- General 这个目录存放会被重用的Views/Classes和Categories
|- Helpers 这个目录存放一些助手类(基类一般为NSObject),文件名与功能挂钩
|- Vendors 这个目录存放第三方的类库/SDK,如UMeng、WeiboSDK、WeixinSDK等等
|- Sections 这个目录下面的文件对应的是app的具体功能模块,是开发的核心区域,其内部结构必须用文件夹组织
|- Resources 这个目录存放除图片外的资源文件,图片资源存放在Images.xcassets中
|- Supporting Files 这个目录存放引用配置文件和pch文件
|
|- AppDelegate.h
|- AppDelegate.m
|- Images.xcassets
PublicModule是为了提高开发效率,将一般引用都需要的功能模块(基类实现,网络访问,数据统计,常用扩展等)独立出来,在前期积累中可能会向其中增加一部分内容。同时为了后续多个项目使用时,需要能够保持其一致性(可能将其托管到GitHub上利用CocoaPods进行管理)。
2.函数定义与调用
函数定义时,在"-"后必须增加一个空格,大括号建议独占一行。如:- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
path:(NSString *)relativePath
parameters:(NSDictionary *)parameters
3.其它要求
对于相同模块或组合功能的函数,必须放在一起,并且增加 pragma mark 标记。
#pragma mark UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
...
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
...
}
二、命名规范
命名规范基本采用骆驼式命名法,命名单词自然连接,能准确描述其含义即可。骆驼式命名法(Camel-Case)又称驼峰命名法,是电脑程式编写时的一套命名规则(惯例)。正如它的名称CamelCase所表示的那样,是指混合使用大小写字母来构成变量和函数的名字。其包含小驼峰法和大驼峰法。
1.类的命名
类的命名采用大驼峰法
如:@interface BaseViewController : UIViewController
2.函数命名
<span style="font-size:14px;">函数命名采用小驼峰法
如:- (void)showTips:(NSString*)tips;</span>
3.变量命名
<span style="font-size:14px;">变量命名采用小驼峰法
如:UIView *titleView;</span>
4.常量命名
常量命名不采用驼峰命名法,命名单词全部大写,单词与单词之间用”_“进行分隔
如:#define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width
三、注释规范
写注释是一种良好的编程习惯,代码注释需追求精简,并不是越多越好,只需要写必要的注释。同时请遵守命名规范和排版规范,做到在iOS中代码是最好的注释。推荐安装Xcode注释工具VVDocumenter-Xcode(
https://github.com/onevcat/VVDocumenter-Xcode)。
小编补充说明:下载好安装程序之后,直接打开文件运行,然后插件就自动安装好了,然后重启Xcode,在你需要添加注释的地方连续敲三下“/”,即可出现代码注释。
1.文件注释
文件的注释,原则上使用系统自动生成的注释,包含文件名、模块名、创建者、创建时间和版权信息。在头文件中,有必要增加一行文件功能描述。格式如下:
//
// BaseNetClient.h
// PublicModule
//
// Created by zhoupengli on 15/4/23.
// Copyright (c) 2015年 Longtu Game. All rights reserved.
// 网络请求客户端基类
2.函数注释
函数注释可以使用VVDocumenter-Xcode插件辅助实现,包含函数功能,输入参数说明和返回值说明。在对外提供接口的头文件中,强制添加该格式注释。格式如下:
/**
* 通用网络请求
*
* @param method POST GET
* @param relativePath 相对路径
* @param parameters 请求参数
* @param success 成功回调
* @param failure 失败回调
*
* @return 网络请求执行实例
*/
3.其它注释
代码片段、实现文件中的内部函数等其它的注释,原则上在代码片段或函数之上,利用“//”简单明了的写一行注释即可。
四、编码规范
1.关于打印Log
请使用MLOG打印日志。可使用NSLog临时打印日志,调试完成后及时删除。禁止提交使用NSLog方式打印日志的代码。相关日志打印宏定义如下:
</pre><pre name="code" class="objc">#ifdef DEBUG
#define SHOW_LOG 1
#else
#define SHOW_LOG 0
#endif
#if TARGET_IPHONE_SIMULATOR | SHOW_LOG
#define MLOG(...) NSLog(__VA_ARGS__)
#define MPRINTF(...) printf(__VA_ARGS__)
#define MSHOW(o) CFShow(o)
#define MLOGFUNCTION printf(" %s Line: %d \n", __FUNCTION__, __LINE__);
#define MLOGCURRENTTIME MLOG(@"current time: [%s-%d: %f]", __FUNCTION__, __LINE__, CFAbsoluteTimeGetCurrent())
#else
#define MLOG(...) //
#define MPRINTF(...) //
#define MSHOW(o) //
#define MLOGFUNCTION //
#define MLOGCURRENTTIME //
#endif
补充说明:
在ios项目开发中,项目发布时需要去掉NSLog消息,不然会非常影响性能,但是去掉NSLog是一件非常费事的事情
解决办法
在项目的目录Supporting Files->项目名称-Prefix.pch,这个项目文件被所有的文件包含了,是一个公用的文件
在文件中添加
#ifdef DEBUG
//调试状态
#define Log(...) NSLog(__VA_ARGS__)
//发布状态
#else
#define Log(...)
#endif
加入这个代码之后,在项目DEBUG的时候
项目中Log(@"num=%d",num);会被自动替换为NSL(@"num=%d",num)执行,在项目的发布状态,Log(...)不会执行
2.关于Block
使用Block可以简化代码,收拢逻辑,提高代码的可阅读性。但是在使用Block时,需要注意避免循环引用,造成内存不释放。为了避免这个问题,需要在Block里面使用弱引用,示例如下:
BlockDemo *demo = [[BlockDemo alloc] init];
__weak typeof(BlockDemo) *weakDemo = demo;
[demo setExecuteFinished:^{
if (weakDemo.resultCode == 200) {
[self callback];;
}
}];
[demo executeTest];
此处利用__weak实现了弱引用,此外还可以将对象本身作为参数传回回调,编译器会自动做弱引用,在设计Block函数时尽量按照这种方式设计。
BlockDemo *demo = [[BlockDemo alloc] init];
[demo setExecuteFinishedParam:^(BlockDemo *backDemo) {
if (backDemo.resultCode == 200) {
[self callback];;
}
}];
[demo executeTest];
另外,由于工程引入了RAC(ReactiveCocoa),可以使用@weakify和@strongify两个宏,来完成弱引用。另外使用RAC的方式时必须使用这个宏来声明self。
BlockDemo *demo = [[BlockDemo alloc] init];
@weakify(demo)
[demo setExecuteFinished:^{
@strongify(demo)
if (demo.resultCode == 200) {
[self callback];;
}
}];
[demo executeTest];
3.关于Warning
原则上,代码中编译器提示warning的位置都需要修改去除warning,对于引入的第三方库也是如此。
Tips
* 为了避免编译器在64位或32位环境下编译产生warning,尽量避免使用int或long定义变量,而使用NSInteger定义变量。
* 格式化输出NSInteger类型数据时,应使用强制类型转换,如(@"%ld",(long)integer)