iOS开发规范

2021-08-19  本文已影响0人  送我迷迭香

前言

为了利于项目维护以及规范开发,促进成员之间Code Review的效率,故提出以下开发规范,如有更好的建议,欢迎提出。


(一)gitlab分支管理、命名


(二)命名规范

代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。正确的英文拼写和语法可以让阅读者易于理解,避免歧义。
*注意:即使纯拼音命名方式也要避免采用。但alibab、taobao、youku、hangzhou等国际通用的名称,可视同英文.

大驼峰规则:每个单词的首字母大写。例:NameTextField。
小驼峰原则:第一个单词首字母小写,其余都大写。例:nameTextField。

1.项目命名

项目名都遵循大驼峰命名。例如:QuickPushCRM

2.类名

类的命名都遵循大驼峰命名。一般是:前缀 + 功能 + 类型。例如:CRM + Login + ViewController

在实际开发中,一般都会给工程中所有的类加上属于本工程的前缀。

常用控件类命名类型对照表(下表中前缀为:CRM,如果用到下表中没有列举出来,请去掉UI首字母,遵循实际规则即可。)

控件名 类型 示例
UIViewController ViewController CRMBaseViewController
UView View CRMBaseView
UITableView TableView CRMOrderTableView
UITableViewCell Cell CRMOrderListCell
UIButton Button CRMSuccessButton
UILabel Label CRMSuccessLabel
UIImageView ImgView CRMGoodsImgView
UITextField TextField CRMNameTextField
UITextView TextView CRMSuggestTextView

其它类相关对照表

功能 类型 示例
工具类 Tool CRMOrderTool
代理类 Delegate CRMOrderListDelegate
管理类 Manager CRMOrderListModel
模型类 Model CRMOrderListModel
Service类 Service CRMOrderService
布局类 Layout CRMHomeLayout
数据库类 DataBase、表名+DBHelper CRMFriendDataBase、CRMUserTableDBHelper
类目 XXX+(范围,例如Extension, Additions 或者功能,例如Frame,Nib,Block) CRMUIButton+Additions、CRMUIButton+Block

3. 方法命名规范

Tips: 给私有方法加前缀有2个好处:

  1. 增加辨识度,提高代码可读性。
  2. 避免自己的方法无意间覆盖了系统/框架同名的私有方法。
正例:
- (CGSize)cellSize;
反例:
- (CGSize)getCellSize;
正例:
- (void)getCachedResponseForDataTask:(NSURLSessionDataTask *)dataTask 
                   completionHandler:(void (^) (NSCachedURLResponse * __nullable cachedResponse))completionHandler;
正例:
- (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag;
反例:
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
正例:
- (id)viewWithTag:(NSInteger)aTag;
反例:
- (id)taggedView:(int)aTag;
正例:
- (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes;
反例:
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
正例:
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;

4. Protocol命名规范

正例:
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
正例:
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;

5. Category命名规范

正例:
UIView (YYAdd)
反例:
UIView (Add)

Tips: 尽管从技术上来讲可以在分类中声明属性,但是这么做需要格外小心,
因为它很容易出现内存上或其他一些问题,而且一旦出现问题很难排查。

6. Notification命名规范

正例:
UIApplicationDidBecomeActiveNotification
UIApplication表示该通知属于谁,DidBecomeActive表示该通知的作用,Notification表示它是一个通知。

Tips:
例如applicationDidBecomeActive:代理方法和NSApplicationDidBecomeActiveNotification通知(这其实也符合命名规范的基本原则"一致性")。

7. 常量命名规范

正例:
// 局部可见
const CGFloat kAnimationDuration = 2.0;
// 全局可见
const CGFloat UIActivityIndicatorViewAnimationDuration = 2.0;

8.变量和方法

变量和方法的命名都遵循小驼峰命名。例如:textVariableStr, - (void)textAction响应事件。

方法命名对照表(方法多为动词或动名词)

功能 示例
- (id)initXX 初始化相关方法,使用init为前缀标识,如初始化布局- (id)initView
- (BOOL)isXX 方法返回值为boolean型的请使用is前缀标识
- (UIView *)getXX 返回某个值的方法,使用get为前缀标识
- (void)setXX 设置某个属性值或者相关数据
- (void)updateXX 更新数据
- (void)saveXX 保存数据
- (void)drawXX 绘制相关,使用draw前缀标识
- (void)clearXX 清除数据
- (void)XXXAction 响应事件,使用Action为后缀标识
- (void)loadData 加载数据(一般情况下VC中都会有这个方法)
- (void)loadMoreData 加载更多数据
- (void)setupUI 加载布局(一般情况下VC中都会有这个方法)

9. 资源文件命名

全部小写,采用下划线命名法,加前缀区分。所有的资源文件都需要加上工程前缀(小写形式)
命名模式:可加后缀_small表示小图,_big表示大图,逻辑名称可由多个单词加下划线组成,采用以下规则:
用途_模块名_逻辑名称
用途_模块名_颜色
用途_逻辑名称
用途_颜色

说明 前缀(工程前缀示例CRM) 示例
按钮相关 crm_btn_ crm_btn_home_normal、crm_btn_red,crm_btn_red_big
背景相关 crm_btn_ crm_bg_home_header、crm_bg_main
图标相关 crm_ic_ crm_ic_home_location、crm_bg_input
分割线相关 crm_div_ crm_ic_home_location、crm_bg_input
默认相关 crm_def_ crm_ic_home_location、crm_bg_input

10. 文件夹命名

创建文件夹最好创建实体文件夹,找到工程目录,创建相应文件夹并拖入工程。文件夹命名使用相应模块结构分层的英文,首字母要大写。例:ModelViewControllerToolOtherService等等。


(三)编码规范

正例:
@interface MineViewController ()

@property (nonatomic, weak) UIView *headView;

@property (nonatomic, weak) UITableView *tableView;

我是换行符,请忽略
@property (nonatomic, copy) NSArray *dataSourceArray;
正例:
[self createSubviews];
[self createTableview];

[self netRequest];
反例:
- (void)dealloc {
    [self unsafeMethod:self];
}
反例:
CFArrayRef arrayRef = (__bridge CFArrayRef)array;

if (x == YES) return;

CFRelease(arrayRef);

以上代码如果x等于YES的话那么arrayRef对象就会内存泄漏。
反例:
@try {
CFArrayRef arrayRef = (__bridge CFArrayRef)array;

do some thing……

CFRelease(arrayRef);

} @catch (NSException *exception) {

}

以上代码如果do some thing……出现异常的话那么arrayRef就会出现内存泄漏。
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) DeliveryModel *delivery;
@property (nonatomic, strong) DeliveryLookAdapter *lookAdapter;
@property (nonatomic, strong) DeliveryLookAPIManager *lookManager;

正例:
i++、++i、
反例:
i ++、++ i
正例:
1 + 2
反例:
1+2
Tips:
1. 第二行相对第一行缩进4个空格,从第三行起不再继续缩进。
2. 运算符与下文一起换行。
3. 方法调用的点符号与下文一起换行。

正例:
- (void)setImageWithURL:(nullable NSURL *)imageURL
            placeholder:(nullable UIImage *)placeholder
                options:(YYWebImageOptions)options
               progress:(nullable YYWebImageProgressBlock)progress
               ransform:(nullable YYWebImageTransformBlock)transform
             completion:(nullable YYWebImageCompletionBlock)completion;

UIViewController请按照如下分类
#pragma mark - Life Cycle
#pragma mark - Private
#pragma mark - Public
#pragma mark - UITableViewDelegate && UITableViewDataSource
#pragma mark - CustomDelegate
#pragma mark - Getters and Setters
#pragma mark - Lazy Loading

注意:所有视图或者对象的创建请尽量使用懒加载,调用的时候全部使用self.textBtn这样的方式。如果是确定的不可变数组、字典,可直接给定数组中的元素。(getters and setters分类中,懒加载可出现_调用对象,其它情况请遵循self.调用原则)

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong)UIButton * textBtn;
@end

@implementation ViewController

#pragma mark - life cycle
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.textBtn];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
#pragma mark - private 

#pragma mark - event response

#pragma mark - UITableViewDelegate && UITableViewDataSource
//(代理顺序往下排列)

#pragma mark - CTAPIManagerCallBackDelegate

#pragma mark - getters and setters
- (UIButton *)textBtn
{
    if (_textBtn == nil) {
        _textBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _textBtn.frame = CGRectMake(300, 250, 100, 100);
        _textBtn.backgroundColor = [UIColor yellowColor];
        _textBtn.titleLabel.text = @"text";
        [_textBtn addTarget:self action:@selector(text) forControlEvents:UIControlEventTouchUpInside];
    }
    return _textBtn;
}
#pragma mark - Lazy Loading

@end


(四) 注释规范

为了减少他人阅读你代码的痛苦值,请在关键地方做好注释。

1.类注释

//
//  CRMNewToNetViewController.h
//  QuickPushCRM
//
//  Created by susu on 2021/6/18.
//  Copyright © 2021 方俊. All rights reserved.
//

该注释是自动生成的,在xcode中设置即可。Created by 电脑用户名on 创建该文件的时间。Copyright 2021 后面的名字和邮箱是自己填写和设置的。具体可在xcode工程,Project Document中设置。这样便可在每次新建类的时候自动加上该头注释。

2.方法注释

方法注释,方法外部统一用option + command + /,方法内部统一用//注释。

/**
 测试
 */
- (void)text
{
    //测试按钮事件响应
}

3.模型注释

每个model中的,包含的每个属性,都必须要写上相对应的注释,用///注释。阅读者一看这个model,就清楚知道model中的每个字段代表的意思,用来做什么事情的。

@interface DeliveryModel : NSObject
///提货劵所在商圈id
@property (nonatomic, assign) long long mallId;
///商圈全称
@property (nonatomic, copy) NSString *mallFullName;
///商圈简称
@property (nonatomic, copy) NSString *mallShortName;
///提货劵号
@property (nonatomic, copy) NSString *credentialsCode;
///总金额
@property (nonatomic, assign) NSInteger totalAmount;
///提货劵所在店铺id
@property (nonatomic, assign) long long storeId;
///货劵所在店铺名称
@property (nonatomic, copy) NSString *storeName;
///提货劵id
@property (nonatomic, strong) NSNumber *credentialsId;
///状态:0:未提货、1:已提货、2:已分享、3:已退款
@property (nonatomic, assign) NSInteger state;
///提货商品(以下为提货商品参数)
@property (nonatomic, strong) NSArray<DeliveryGoodslist *> *goodsList;
///二维码
@property (nonatomic, copy) NSString *qrCode;
///商品总个数
@property (nonatomic, assign) NSInteger goodsCount;
@end

如果不是model的属性,是其它类属性,需要注释,请按照model属性注释方式。

正例:
/**
* @brief 简要描述
* @author 标明开发该类模块的作者
*/
// FIXME: 有bug,需要修改
- (void)testFunction;

(五) 版本规范

采用A.B.C 三位数字命名,比如:1.0.2,当有版本更新的时候,依据下面的情况来确定版本号规范。

版本号 说明 示例
A.b.c 属于重大更新内容 1.0.2 -> 2.00
a.B.c 属于小部分更新内容 1.0.2 -> 1.2.2
a.b.C 属于补丁更新内容 1.0.2 -> 1.0.4

(六)第三方库规范

希望Team能用时下较新的技术,对开源库的选取,一般都需要选择比较稳定的版本,作者在维护的项目,要考虑作者对issue的解决,以及开发者的知名度等各方面。选取之后,一定的封装是必要的。

项目使用cocoapods统一管理开源第三库文件,不需要手动导入和手动添加依赖库。如果第三方不支持cocoapods,可手动导入工程。


(七)其它规范

上一篇下一篇

猜你喜欢

热点阅读