一:设计模式
1:本项目采用mvvm设计模式,每个模块下分为四个文件夹,分别为:Controller
View
ViewModel
Model
Controller
:控制器文件夹 在此文件夹中只存放模块相关控制器,控制器中只做UI初始化 刷新UI 响应用户事件 跳转逻辑判断等和业务无关操作,所有业务处理放到ViewModel
中处理
View
:自定义视图文件夹 在此文件夹中存放该模块相关的视图,比如自定义的cell,定制的view等.
Model
:数据模型 如果一个view需要设置的属性比较多,建议创建一个数据模型,并通过数据模型去给view赋值
ViewModel
:业务逻辑管理 这此处理模块相关的业务逻辑,比如:网络请求 各种代理 数据逻辑判断(PS:输入数据是否合法)等, 并通过block
方式提供处理结果给Controller
使用,这里不建议使用通知方式返回结果
二:项目框架整体结构,如下图所示
1:Frameworks
文件夹 存放系统库的虚拟文件夹,搭建框架的时候需要手动添加一个名称为Frameworks的虚拟文件夹,这样在Build Phases 中添加的系统库会自动归入此文件夹,不会直接在外部显示以至于打乱目录结构
2:AppDlegate
文件夹 这个目录下放的是AppDelegate.h(.m)文件,是整个应用的入口文件,这里需要添加一些入口相关类以保持一个简洁的AppDelegate,所以单独建立了一个文件夹
3:Class
文件夹 项目业务主体,日常大部分开发代码均在这里,里面包含项目所有的业务逻辑,下图创建了三个大的分类业务,每个业务下面的小业务再次分层次实现
4:
Gategory
文件夹 主要用来存放公共扩展类,主要存储一些对系统库的扩展5:
Libs
文件夹 主要存放要用到的第三方类库和项目中自己实现的公共类库,可分文件夹分别存储. 本项目也用到cocopods
管理第三方库,如果是不需要改动源码直接使用的建议使用cocopods
管理,如果需要改动源码,强烈建议直接放入Libs
文件夹中管理,以免更新pods代码时把修改的代码更新掉6:
Global
文件夹 存放全局的配置文件,包括pch文件,一些全局的宏定义文件等7:
Utils
文件夹 项目相关辅助类,存放相关的数据请求,支付相关类,数据库操作相关类等8:
General
文件夹 通用类,存储项目移植过程中不需要更改就能直接使用的类9:
Resource
文件夹 资源文件夹,用来存放和项目有关的资源,比如图片资源,文件资源等10:
Base
文件夹 基类,存储项目中需要用到的基类,比如全局初始化的viewController父类, 弹窗父类, 展示表父类等
三:模块结构
1:每个大的模块如果含有较多的小模块建议多次分级(文件夹),以避免在一个模块中放入过多的类代码导致查找麻烦
2:模块命名可以汉字也可以英文,但要做到见名知意,比如:
四: 类结构
1: 命名: 所有的命名都要做到见名知意, 使用英文,并且结尾要使用能表明该类或者属性 类型的文字(PS: viewController label button array model viewModel等)
1.1 采用大驼峰命名法,PS:PayHistoryViewController
(表明是 支付历史 并且是个 控制器)
1.2: 属性命名: 采用小驼峰命名, 属性和属性之间换行已做区分, 实例变量命名要用 _xxx
方式
{
// 数据源
NSArray *_dataArray;
// 存放选中cell的字典
NSDictionary *_selectedCellDic;
}
如果是全局属性并且在.h文件中,使用文档注释表明属性的作用,(要注意空格 比如 @property
(nonatomic, strong)
UILabel
后面都有空格)如:
/**
* 剩余签章次数
*/
@property (nonatomic, strong) UILabel *timesTextLabel;
/**
* 勾选
*/
@property (nonatomic, strong) UIButton *checkBtn;
/**
* 我已阅读并同意
*/
@property (nonatomic, strong) UILabel *readLabel;
如果在.m文件中,使用 //
注释说明 表明属性的作用,如:
// 剩余签章次数
@property (nonatomic, strong) UILabel *timesTextLabel;`
// 勾选
@property (nonatomic, strong) UIButton *checkBtn;`
// 我已阅读并同意
@property (nonatomic, strong) UILabel *readLabel;
如果是局部变量,根据情况判断是否要加注释(只需要加 //
注释);
1.3 方法命名 同样的采用小驼峰命名, 注释方式和属性相同,如有必要可以添加#pragma mark
注释, 如果有参数,并采用多行注释如有必要要在注释中 表明 参数的含义. 当参数较多时要换行以方便查看.如:
/**
* 在window上展示
* model :数据模型
* signUnitPrice :单价
* payTapBlock :支付点击事件
* cancelTapBlock :取消支付点击事件
- (void)showWithProduct:(PayProductModel *)model
signUnitPrice:(NSInteger)signUnitPrice
payTapBlock:(void(^)(void))payTapBlock
cancelTapBlock:(void(^)(void))cancelTapBlock;
方法声命和实现时要注意空格,-
(或者+
)后面要有空格,{
前面有空格,后面换行,方法和方法之间要换行,
2: 结构:
2.1 首先是 头文件导入
2.2 全局属性定义 相关宏定义 常量定义
2.3 声命周期函数
2.4 用户交互事件操作(各种点击事件,刷新事件,界面跳转事件)
2.5 子视图初始化
五: 补充
5.1 简写补充 在定义属性和方法时, 可以使用众所周知的简写代替
5.2 事件补充 点击事件使用 xxxTapAction
长按事件使用xxxLongPressAction
5.3 block补充 block声命时 要使用 copy
, 命名时要使用大驼峰命名法,如:@property (nonatomic, copy) void (^PayTapAction)(void);
5.4 空格位置补充 所有的操作符前后要加空格如: +
-
*
/
&&
||
<
>
=
等
// 这里要主要空格
for (int i = 0; i < 3; i++) {
}
if (1) {
} else {
// 这里else不要换行
}
while (1) {
}
// 这里break和 default不能忘记
switch (1) {
case 1:
break;
default:
break;
}