iOS 技术浅谈之第五篇(编程规范篇)

一、排版规范

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];

以上三处代码,由于demo是临时变量,在其Block中调用self的方法不会造成循环引用。但如果demo是self的成员变量,那么在使用Block的时候,也需要对self进行弱引用。

3.关于Warning
原则上,代码中编译器提示warning的位置都需要修改去除warning,对于引入的第三方库也是如此。
Tips
* 为了避免编译器在64位或32位环境下编译产生warning,尽量避免使用int或long定义变量,而使用NSInteger定义变量。
* 格式化输出NSInteger类型数据时,应使用强制类型转换,如(@"%ld",(long)integer)







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值