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代码顶部有大气底初始化代码,这就算招重大的逻辑代码挪到背后去了,其他人阅读代码是无太便宜的。

结尾

夜深人静,该睡觉了。欢迎收藏之
自家之博客