公司须要写一个代码规范,本人第一次写,完成后记录在blogweb
1、命名规范数据库
一、类定义编程
例: ThisIsAClass,
采用苹果推荐的方式,首字母大写,多个有实际意义的英文单词组成,每一个单词的首字母大写。json
在此基础上类名须要体现出这个类的类型swift
试图控制器:ThisIsAViewController
试图:ThisIsAView
按钮:ThisIsAButton
等等数组
我的不建议使用缩写,由于代码补全很是完善,单词再长也不会影响方便性,但缩写影响可读性
可讨论决定是否可以使用相似 ThisIsAVC,ThisABtn,之类的缩写方式缓存
二、属性安全
例:thisIsAObjectruby
首字母小写,多个有实际意义的英文单词组成,每一个单词的首字母大写。bash
在此基础上,须要提示这个变量的类型或者用途。
例如:
UITextField * userNameTextField;
UIButton * leftTopButton,doSomeActionButton;
等等
缩写问题同上,可讨论。
三、成员变量
_menberObject
在属性的基础上,须要如下划线开头。
其余规则和属性同样。
四、局部变量
参照属性
五、函数命名
首字母小写,多个有意义的单词组成,:后面首字母小写
例:
- (void)loginButtonDidPressed; - (void)loginWithUserName:(NSString) userName password:(NSString *) password;
等等
六、函数形参
参照属性
如有可能与属性命名相同或者冲突,建议加上in,a等前缀
例:
- (void) someMethod:(id) inValue anotherObject:(id) aObject
{
_vlaue = inVlaue;
self.object = aObject;
}
7 、前缀
因为oc没有命名空间的概念,全部苹果建议使用前缀来防止第三方库、子工程之间命名冲突。
目前咱们的工程中有的没有前缀,有前缀的又不统一,须要讨论是否统一。
2、代码组织
一、概述
目前咱们的工程都采用MVC构架
因此页面代码都至少要包含,View(特别简单的可能省略),VewController(UIVewController子类),ModelManager(这么命名是区分于瘦model,也就是entity)
三者之间最好经过接口互相访问,隐藏实现细节。
好比,VC不须要知道view有哪些label,textfileld,只须要view提供加载数据的方法就能够,实现松耦合。这样若是只是页面排版变了,只要修改接口实现就能够,不用修改其余部分。这也是swift发布后,苹果提出的面相接口(协议)编程的思想。
规则提出的目的,都是指导咱们对各模块之间职能划分,使各自功能单一,松散耦合,任一一方修改,尽量的不影响其余模块。
二、页面
UIView:只作显示逻辑不作业务逻辑,它应该是纯被动的接受VC提供的数据,进行展现。
对用户操做进行收集,提示VC事件发生。
下面提供一些开发场景的处理建议:
case 1
若是view包含一个imageview,性别变量sex,值为male,显示图a,sex为female,显示图b,这种逻辑应该在VC中实现,而不该该把sex传给给View去保存。
//VC中
- (void) someMethod
{
if (self.sex == male) //假设male为枚举
{
[view loadImage:imageA];
}
else
{
[view loadImage:imageB];
}
}
//view中
- (void)loadImage:(UIImage *)inImage
{
self.imageView.image = inImage;
}
case 2
不要在init方法中,去取自身的frame,并以此对子view设置frame,而应该在layoutSubviews中设置
由于不少时候,init方法中,view自己的frame并非最后显示的frame
- (void)layoutSubviews
{
// 必定要调用super的方法
[super layoutSubviews];
//子view的frame设置
…
}
case 3
只是堆砌子View的状况通常不太须要自定义view。
自定义view,其实更应该发生在须要重载drawRect方法,或者事情响应touchesBegan/touchesEnded等方法时。而大部分状况其实不须要重载这些方法。只须要addSubvew。
这种状况其实更应该考虑是建一个子视图控制器,毕竟管理一个视图层级(view hierarchy)是VC的事情。
三、视图控制器
试图控制器负责:从而且只从modelManager获取数据,展现到View上。而且接受modelManager数据变化发生时通知,提供回调方法。
开发场景:
case 1
loadView:通常不建议重载,实在要用根据文档所诉,只应该建立视图层级(view hierarchy)也就是只应该作alloc和addSubview。而且若是重载它了,不要调用super,额外的赋值需在viewDidload以后再作。
注意:若是使用了xib或者storyboad就不要重载这个函数。而应该使用awakeFromNib。
case 2
viewDidload:做为入口,但愿它能比较简洁直观,因此建议它内部只出现toDoList型的函数,具体的实现到各个函数中实现。
例如:
- (void) viewDidLoad
{
[super viewDidLoad];
[self setupViews];
[self registerNotifications];
[self setupModelManager];
[self doOtherThing];
}
建议在viewDidload中使用自动布局来管理View及子view的frame
case 3
viewwill/DidlayoutSubviews:这对函数在 view调用layoutSubviews先后调用。若是你没用使用自动布局,应该在这两个函数中对view进行位置的设置。
case 4
关于展现用的数据,除非必要,不建议用额外的属性/成员变量保存。而直接经过modelManager的函数得到。以便由modelManager控制数据保存的位置是内存变量,仍是持久化方式。
实在须要在内部函数间传递,也尽可能根据最小知道原则,保存索引,状态值之类的数据。
四、modelManager
modelmananger负责从一个或多个数据源,采集数据业务操做后提供给VC,数据来源多是数据库,内存缓存,网络等中的一个或多个。
开发场景
case 1
对VC隐藏数据源的原始数据结构。
也就是说尽可能不要把数据源原始数据直接交给VC,而应该与VC约定好相互之间须要传递的最小单元(实体/瘦model),把从一个或多个数据源获取的原始数据,转化成该最小单元。提供给VC
case 2
与VC交互的协议接口定义,应足够独立,一个事件/一次数据请求,一般不该该须要调用到其余接口(这里不是说不能调其余内部函数,而是对VC 开放的其余接口)
case 3
接口实现优先进行内存操做,内存没有的数据再操做数据库,尚未再进行网络操做。实现多级缓存及时反馈。
case 4
页面之间的数据变动响应,应该在modelManager之间通知和响应
具体来讲:
vc1某操做,致使vc1的modelManager有数据变动,这个变动影响到v2,那么不该该由v2去接受这个变动通知,而应该由vc2的modelManager接受并修改自身的数据,经过本身的数据变动接口通知vc2。
也就是说一个VC只接受一个modelManager的数据更新通知。
case 5
尽管上面的建议一个VC只对应一个modelManager。但有些场景下,多个VC能够共享一个modelManager。
例:
设置功能下有多个子设置项,这些设置项是不一样子页面操做去设置的而且很简单,当咱们把设置项的数据做为一个总体去考虑的时候,这些子设置项操做的其实应该是同一个数据对象。此时应该支持这些页面传递modelManager对象来共享它。
五、其余衍生组件
在MVC的框架下,可根据功能单一原则,拆分出多个功能组件,供三大框架模块使用,好比数据库模块,网络模块,加密模块,播放器模块等等。
3、代码优化建议
case 1
任何状况下老是使用setValue:forKey代替setObject:forKey
由于前者在value非nil状况下等于后者。
在value为nil删除key所对应的键值。因为赋值时通常当前并不会存在key的键值,即便是覆盖某对键值,在值为空的状况下,删除了它也是合理的。
因此前者效果彻底等效于检测value非空后调用后者。
后者object为nil则直接crash。
因此使用setValue:forKey更安全。
case 2
隐藏没必要要的接口和属性。
那些只在内部使用的属性和函数,应定义在类扩展之中,把少数愿意暴露出去的函数和属性定义在头文件中。
case 3
尽可能不要使用成员变量,用类扩展中的属性代替它。而后老是使用self.去访问它。
这样有更清晰的内存管理。
而且,当有一天你忽然须要在赋值或者取值的时候作一些事情的时候,你就只须要在set/get中操做。而不用整个类里面处处修改了。
case 4
尽可能不要阻塞主线程,尽可能把非UI操做放到其余线程执行,完成后回到主线程通知UI刷新。
case 5
NSSet/NSArray,他们的区别是,NSSet是无序的,当一个数据集合不关注排序时,使用NSSet,查找元素是否存在和移除效率是高于NSArray的。
例:
维护一个操做中的数据集合,操做开始后加到集合中,操做完成后移除出集合,这种状况下应当使用NSSet
case 6
不管何时经过索引访问数组都应该进行越界判断。或者try catch
case 7
懒加载,对不经常使用的View,不要在页面打开时就建立,采用懒加载的方式去实现。以减小页面启动时间。
case 8
预加载,对于加载速度比较慢,又须要进入页面就直接显示的数据,考虑在适当的时间提早加载好,驻留在内存中。空间换时间。
case 9
tableView的使用除了注意cell正确重用之外,还需注意,数据源的count变化,特别是变小是要及时reloadData。若是使用insertRow/removerow操做,必定要保证数据源数量等于变化前数量加/减变化数量,不然就会crash
case 10
实体中只能进行简单的数据操做,例如json转字典,数值转字符,取整之类的。不能进行业务操做,如存取数据库,网络操做等。
case 11
使用大量临时变量时,可用@autoreleasepool来包含起来及时释放。