iOS架构师之路:制定代码规范

前言

先吹个牛,我起心眼自认为好是爱对团项目之代码质量负责的口,对于想如何勾勒来强质量可读性的代码我是乐此不彼。之前我形容了一点儿首关于代码命名规范与代码编写规范的篇章,《iOS架构师之路:iOS开发(OC)中之命名规范》、《iOS架构师之路:IOS项目面临之编码规范》,您要是是情绪很好,就夺看看吧,如果低于生好,那非建议乃看,怕你心里骂娘,因为今羁押,感觉自己写的非极端认真,有诸多方可描绘的重仔细,恩,我主宰为好帖贴金,不克如此说好:其实这半年略哥我在代码规范者的知而展现涨不丢,所以看以前定制的正规不爽,作为绑架构师保持谦虚,通过持续上,不断自我修正,对代码有好几洁癖是该有的派头(潜台词其实我思念说我生)。制定项目之代码规范对架构师的重中之重,就如如果你特别个娃一如既往,责任重大,万一生出来缺胳膊少腿,娶不至女,你之后就伺候他终身,给他当牛做马,他吧非必然会念你的好。

按代码规范之要害

  • 1.架构师要呢整项目技术可行性的开拓进取负责,所以制定一个优良的代码规范,让开发工程师遵守,有利于项目为您预知的自由化前进。比如当你往利用AOP技术实现日志功能时,就用规定部分计命名。
  • 2.一样的代码规范,有利于代码reveiw工作。如果每个工程师写的代码风格不相同,review代码的同事,阅读起来肯定不顺畅。
  • 3.渴求工程师按照代码规范写来一致的代码,就不怕他跳槽。这行本来就浮躁,流动性好,要是工程师写的代码风格就发生他协调能看明白,那东西他跳槽,新人是那个为难继续维护这部分代码的,得不偿失。

培植代码洁癖

深受大家推荐一遵循有关代码规范之力作,第一照:《禅与 Objective-C
编程艺术(Zen and the Art of the Objective-C Craftsmanship
中文翻译)》(简称:Zen),这按照开开始源社区的大牛,无偿奉献出的,该书于我们介绍许多描写代码的对姿势,并分解为何以此姿势体验更好。看了马上按照开应当明白如何勾勒有优雅、高可读性并且可靠的代码了。

我推荐的代码规范

《The Objective-C Style Guide used by The New York
Times》(简称:New
York,该标准为有中文版),《New
York》是自个儿于好的编码规范风格,它是《Zen》的编码思想一个格外好之执行。

至于《Zen》、《New York》代码规范之补偿

1.iOS切图文件的命名规范

即部分标准或者是挺有经验的宏图提供,也闹或是咱们开发人员提供,掌握总是没有坏处的。

咱的命名规则之中心思维是拿公文称分成三局部,第一局部凡图的逻辑归属分类,第二片凡是图片的呈现内容,第三组成部分凡图表的始末之门类,有些图片还会有第四有些,表示图片表现的状态。首先有几乎独规则是:

  • 故此英文命名,不用拼音
  • 各一样局部用生划线分隔
  • 图片名遭有数倍增图于名字最后要加@2x,三加倍图在名字最后使加@3x

万可知公式

image_naming_guideline.png

2.类的布局

先后布局之目的是显示有程序可以的逻辑结构,提高程序的准头、连续性、可读性、可维护性。更要紧的凡,统一之程序布局以及编程风格,有助于提高全体项目的开销品质,提高开支效率,降低开发成本。同时,对于普通程序员来说,养成良好的编程习惯有助于增强协调的编程水平,提高编程效率。因此,统一之、良好的次第布局及编程风格不仅仅是个体主观美学上之或形式达到的题材,而且会波及到产品质量,涉及到村办编程能力的滋长,必须引起大家重视。

2.1.文件布局

【规则2-1-1】遵循统一之布局顺序来修头文件。

说明:以下内容如果某些节不需要,可以忽略。但是任何节要保持该次序。**
**
头文件布局:

文件头
#import (依次为标准库头文件、非标准库头文件)
全局宏
常量定义
全局数据类型
类定义

正例:

/***************************************************************************
 *                                文件引用
 ***************************************************************************/ 
/***************************************************************************
 *                                 类引用
 ***************************************************************************/

/***************************************************************************
 *                                 宏定义
 ***************************************************************************/
/***************************************************************************
 *                                 常量
 ***************************************************************************/ 
/***************************************************************************
 *                                类型定义
 ***************************************************************************/ 
/ ***************************************************************************
 *                                 类定义
 ***************************************************************************/

【规则2-1-2】遵循统一之布局顺序来书写实现文件。
说明:以下内容如果某些节不欲,可以忽略。但是其他节要保持该次序。
兑现文件布局:

文件头(参见“注释”一节)
#import (依次为标准库头文件、非标准库头文件)
文件内部使用的宏
常量定义
文件内部使用的数据类型
全局变量
本地变量(即静态全局变量)
类的实现

正例:

/***************************************************************************
 *                                文件引用
 ***************************************************************************/ 
/***************************************************************************
 *                                 宏定义
 ***************************************************************************/
/***************************************************************************
 *                                 常量
 ***************************************************************************/ 
/***************************************************************************
 *                                类型定义
 ***************************************************************************/
/***************************************************************************
 *                                全局变量
 ***************************************************************************/
/***************************************************************************
 *                                 原型
 ***************************************************************************/
/ ***************************************************************************
 *                                类特性
 ***************************************************************************/
/ ***************************************************************************
 *                                类的实现
 ***************************************************************************/
2.2类组织布局

使用#pragma mark –来分类方法

#pragma mark – Life Cycle

#pragma mark - Events

#pragma mark – Private Methods

#pragma mark - UITextFieldDelegate

#pragma mark - UITableViewDataSource

#pragma mark - UITableViewDelegate

#pragma mark - Custom Delegates

#pragma mark – Getters and Setters
2.3布局中之空格

每个方法要功能块之间以组织清晰,应当有且仅来一行空格。

@interface SomeClass:NSObject

@property (noatomic, strong) UIView *aView

- (void)someMethod;

@end

@implementation SomeClass

- (void)setAView:(NSInteger )aview {

}

- (void)someMethod {

}
@end
2.4有关布局中之Private Methods块,正常情况下ViewController里面不应有写

免是delegate方法的,不是event response方法的,不是life
cycle方法的,就是private
method了。对之,正常状态下ViewController里面一般是匪见面有private
methods的,这个private
methods一般是用于日期换算、图片裁剪啥的这种多少作用。这种小作用要拿它们形容成一个category,要么把他做成一个模块,哪怕是模块只来一个函数也实施。
ViewController基本上是大多数工作的载体,本身代码都相当复杂,所以与工作涉及不慌的东西会不在ViewController里面就毫无放。另外一些,这个private
method的效用这时候只是你用得,但是前或别的地方吗会见因此到,一开始即独自出来,有利于将来底代码复用。

3.属性初始化放哪最好?建议于Getter中初始化

本人来看众多APP,甚至自己公司的品种,很多支出工程师,初始化属性之职务于轻易,有单独添加一个初始化方法类似setupView的,有于init初始化的,各种状况都有,我实际十分崩溃的,首先初始化方式不等同,其次为这么做老有或坏了每个方法效果的单一性(每个方法就开同样码事)。我于习惯一个靶的”私有”属性写以extension里面,然后这些性之初始化全部在getter里面做,在init和dealloc之外,是休会见起任何像样_property这样的写法的。就是这么:

@interface CustomObject()

@property (nonatomic, strong) UILabel *label;

@end

@implementation

#pragma mark - getters and setters

- (UILabel *)label {
    if (_label == nil) {
        _label = [[UILabel alloc] init];
        _label.text = @"1234";
        _label.font = [UIFont systemFontOfSize:12];
        ... ...
    }
    return _label;
}
@end
#pragma mark - life cycle

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.label];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.label.frame = CGRectMake(1, 2, 3, 4);
}

唐巧说他喜好的做法是为此_property这种,然后关于_property的初始化通过[self setupProperty]这种做法去举行。从刚刚者的代码来拘禁,就是要在viewDidLoad里面大多调用一个setup方法而已,然后我推荐的方就是是永不多调一个setup方法,直接走getter。

啊,怎么说呢,其实简单栽做法还能够成就需求。但是打其他一个角度看,苹果用选择于[self getProperty]self.property足相互通用,这种做法已经非常明确地表述了苹果之支持:希望每个property都是经getter方法来赢得。

早于2003年,Allen Holub就作了首稿子《Why getter and setter methods are
evil》,自此之后,业界就本着这个产生了各种争议,虽然是从Java开始说之,但是发展到背后各种语言也涉足了进入。然后虽然现在关于此问题讨论得丢了,但是仍属于无敲定的状态。setter的状态比较复杂,也未是自我当下无异于节省的主要,我顿时边还是要说getter。我们由objc的规划来拘禁,苹果的设计者更加倾向于getter
is not evil。
认为getter is
evil的原由发生良之多,或大或小,随着争论的开展,大家慢慢便聚焦到这么的一个缘故:Getter和Setter提供了一个力所能及为外部修改对象中数据的方法,这是evil的,正常情形下,一个目标好个人的变量应该是只有协调关心。

然后我们回去iOS领域来,objc也一样面临了这般的题目,甚至更为严重:objc并不曾如Java那么严峻的个体概念。但每当骨子里工作受到,我们不太会错过操作头文件之中没有底变量,这是打正规上便吃取缔的。

认为getter is not
evil的缘故也得以聚焦到一个:高度的封装性。getter事实上是厂方法,有矣getter之后,业务逻辑可以更小心让调用,而不用顾虑当前变量是否可用。我们可想转手,假要一个ViewController有20只subview要进入view中,这20独subview的初始化代码是一定逃不丢掉的,放在何比好?放在哪里还比位居addsubview的地方好,我个人认为绝好的地方还是放在getter里面,结合单例模式后,代码会十分整齐,生产的地方与采取的地方得了颇好的别。
因此放到iOS来说,我还是觉得用getter会比较好,因为evil的地方在iOS这边基本都避了,not
evil的地方还能够享用到,还是不错的。

4.Getters and Setters放在最底部

自事先写代码一直拿Getters and Setters
放在implementation的最前方,昨天羁押大神casatwy说不过好放在最后当,我当重新有道理。控制器可能会见有大多之view属性和其他性能,如果所有的getters
and
setters放在眼前,就会促成在implementation代码顶部有雅量的初始化代码,这就算造成重大的逻辑代码挪至后面去了,其他人阅读代码是免绝方便之。

结尾

夜深,该上床了。欢迎收藏之
自己的博客