1.指导原则

【原则1-】首先是为人编写程序,其次才是计算机。
说明:这是软件开发的基本要点,软件的生命周期贯穿产品的开发、测试、生产、用户使用、版本升级和后期维护等长期过程,只有易读、易维护的软件代码才具有生命力。
【原则1-】保持代码的简明清晰,避免过分的编程技巧。
说明:简单是最美。保持代码的简单化是软件工程化的基本要求。不要过分追求技巧,否则会降低程序的可读性。
【原则1-】编程时首先达到正确性,其次考虑效率。
说明:编程首先考虑的是满足正确性、健壮性、可维护性、可移植性等质量因素,最后才考虑程序的效率和资源占用。
【原则1-】编写代码时要考虑到代码的可测试性。
说明:不可以测试的代码是无法保障质量的,开发人员要牢记这一点来设计、编码。实现设计功能的同时,要提供可以测试、验证的方法。
【原则1-】函数(方法)是为一特定功能而编写,不是万能工具箱。
说明:方法是一个处理单元,是有特定功能的,所以应该很好地规划方法,不能是所有东西都放在一个方法里实现

2.布局

程序布局的目的是显示出程序良好的逻辑结构,提高程序的准确性、连续性、可读性、可维护性。更重要的是,统一的程序布局和编程风格,有助于提高整个项目的开发质量,提高开发效率,降低开发成本。同时,对于普通程序员来说,养成良好的编程习惯有助于提高自己的编程水平,提高编程效率。因此,统一的、良好的程序布局和编程风格不仅仅是个人主观美学上的或是形式上的问题,而且会涉及到产品质量,涉及到个人编程能力的提高,必须引起大家重视。

2.1.文件布局

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

说明:以下内容如果某些节不需要,可以忽略。但是其它节要保持该次序。 

头文件布局:

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

正例:

/***************************************************************************

*                                文件引用

***************************************************************************/

/***************************************************************************

*                                 类引用

***************************************************************************/

/***************************************************************************

*                                 宏定义

***************************************************************************/

/***************************************************************************

*                                 常量

***************************************************************************/

/***************************************************************************

*                                类型定义

***************************************************************************/

/ ***************************************************************************

*                                 类定义

***************************************************************************/

【规则2-1-2】遵循统一的布局顺序来书写实现文件。


说明:
以下内容如果某些节不需要,可以忽略。但是其它节要保持该次序。

实现文件布局:

文件头(参见“注释”一节)

#import (依次为标准库头文件、非标准库头文件)

文件内部使用的宏

常量定义

文件内部使用的数据类型

全局变量

本地变量(即静态全局变量)

类的实现

正例:

/***************************************************************************

*                                文件引用

***************************************************************************/

/***************************************************************************

*                                 宏定义

***************************************************************************/

/***************************************************************************

*                                 常量

***************************************************************************/

/***************************************************************************

*                                类型定义

***************************************************************************/

/***************************************************************************

*                                全局变量

***************************************************************************/

/***************************************************************************

*                                 原型

***************************************************************************/

/ ***************************************************************************

*                                类特性

***************************************************************************/

@implementation ClassName

/ ***************************************************************************

*                                类的实现

***************************************************************************/

2.2类结构布局

使用#pragma mark –来分类方法
#pragma mark – Getters and Setters

#pragma mark – Life Cycle

#pragma mark - Events

#pragma mark – Private Methods

#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate #pragma mark - Custom Delegates

2.2.1布局中的空格

每个方法或者功能块之间为了结构清晰,应当有且只有一行空格。

#interface SomeClass:NSObject

@property (noatomic, strong) UIView *aView

-(void)someMethod;

@end

@implementation SomeClass

- (void)setAView:(NSInteger )aview {

}

-(void)someMethod {

}

@end

2.2.2关于布局中的Private Methods块,正常情况下ViewController里面不应该写

不是delegate方法的,不是event response方法的,不是life cycle方法的,就是private method了。对的,正常情况下ViewController里面一般是不会存在private methods的,这个private methods一般是用于日期换算、图片裁剪啥的这种小功能。这种小功能要么把它写成一个category,要么把他做成一个模块,哪怕这个模块只有一个函数也行。

ViewController基本上是大部分业务的载体,本身代码已经相当复杂,所以跟业务关联不大的东西能不放在ViewController里面就不要放。另外一点,这个private method的功能这时候只是你用得到,但是将来说不定别的地方也会用到,一开始就独立出来,有利于将来的代码复用。

2.2.3属性初始化放哪最好?建议:Getter和Setter

我看到很多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的地方都能享受到,还是不错的。

3.表达式

3.1 if语句

表达式大括号和其他大括号(if/else/switch/while 等.)总是在同一行语句打开但在新行中关闭。如果没有else 并且括号内只有一行语句,可以和if语句同行,并且不需要括号。

if (user.isHappy) {
//Do something
} else {
//Do something else
} if (somethingIsBad) return something;

3.2switch语句

大括号在case语句中并不是必须的,除非编译器强制要求。当一个case语句包含多行代码时,大括号应该加上。

switch (condition) {
case :
// ...
break;
case : {
// ...
// Multi-line example using braces
break;
}
case :
// ...
break;
default:
// ...
break;
}

当在switch使用枚举类型时,'default'是不需要的。例如:

RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;
switch (menuType) {
case RWTLeftMenuTopItemMain:
// ...
break;
case RWTLeftMenuTopItemShows:
// ...
break;
case RWTLeftMenuTopItemSchedule:
// ...
break;
}

4.注释

代码中尽量少注释,让代码能自我描述。不过当需要注释的时候,能需要清除的解释某个代码块的含义和作用。注释应当保持最新,如果不必要请删除。

4.代码规范要点

不要在viewDidLoad里面初始化你的view然后再add,这样代码就很难看。在viewDidload里面只做addSubview的事情,然后在viewWillAppear里面做布局的事情最后在viewDidAppear里面做Notification的监听之类的事情。至于属性的初始化,则交给getter去做。

#pragma mark - life cycle

- (void)viewDidLoad {

    [super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.firstTableView];
[self.view addSubview:self.secondTableView];
[self.view addSubview:self.firstFilterLabel];
[self.view addSubview:self.secondFilterLabel];
[self.view addSubview:self.cleanButton];
[self.view addSubview:self.originImageView];
[self.view addSubview:self.processedImageView];
[self.view addSubview:self.activityIndicator];
[self.view addSubview:self.takeImageButton];
} - (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGFloat width = (self.view.width - ) / 2.0f;
self.originImageView.size = CGSizeMake(width, width);
[self.originImageView topInContainer: shouldResize:NO];
[self.originImageView leftInContainer: shouldResize:NO];
self.processedImageView.size = CGSizeMake(width, width);
[self.processedImageView right: FromView:self.originImageView];
[self.processedImageView topEqualToView:self.originImageView]; CGFloat labelWidth = self.view.width - ;
self.firstFilterLabel.size = CGSizeMake(labelWidth, );
[self.firstFilterLabel leftInContainer: shouldResize:NO];
[self.firstFilterLabel top: FromView:self.originImageView];
... ...
}

这样即便在属性非常多的情况下,还是能够保持代码整齐,view的初始化都交给getter去做了。总之就是尽量不要出现以下的情况:

- (void)viewDidLoad {
[super viewDidLoad];
self.textLabel = [[UILabel alloc] init];
self.textLabel.textColor = [UIColor blackColor];
self.textLabel ... ...
self.textLabel ... ...
self.textLabel ... ...
[self.view addSubview:self.textLabel];
}

IOS中的编码规范的更多相关文章

  1. [iOS翻译]Cocoa编码规范

        简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...

  2. iOS中书写代码规范35条小建议

    1.精简代码, 返回最后一句的值,这个方法有一个优点,所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染.但缺点是可读性比较差 NSURL *url = ({ ...

  3. 直播二:iOS中硬编码(VideoToolBox)

    硬编码相对于软编码来说,使用非CPU进行编码,如显卡GPU.专用的DSP.FPGA.ASIC芯片等,性能高,对CPU没有压力,但是对其他硬件要求较高(如GPU等). 在iOS8之后,苹果开放了接口,并 ...

  4. ios中base64编码

    参考文章:其中文章的:http://blog.csdn.net/ztp800201/article/details/9470065 下载包 其中 包括GTMBase包下载地址 http://pan.b ...

  5. IDEA中FindBugs编码规范工具使用

    IDEA中安装FindBugs插件: file--Settings--Plugins 在Plugins搜索FindBugs: 安装完成后在项目中选中文件右键找到findBugs: 检查代码结果: 按照 ...

  6. PHP编码规范PSR-2

    .note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...

  7. 标准的Java编码规范手册

    编码规范体现出一个开发者的基本素质,良好的编码规范可以提高团队编码的效率,避免很多不必要的问题.今天分享一个标准的Java编码规范给大家,希望对于大家今后的开发工作带来帮助. 编码规范的意义      ...

  8. 浅谈 JavaScript 编程语言的编码规范

    对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...

  9. Discuz代码研究-编码规范

    Discuz中的编码规范很值得PHP开发人员借鉴.里面既介绍了编码时代码标记,注释,书写规则,命名原则等方面基础的内容,对代码的安全性,性能,兼容性,代码重用,数据库设计,数据库性能及优化作了阐述,这 ...

随机推荐

  1. Kafka是如何实现高吞吐率的

    Kafka是如何实现高吞吐率的 原创 2016-02-27 杜亦舒 性能与架构 Kafka是分布式消息系统,需要处理海量的消息,Kafka的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的 ...

  2. zabbix3.0.4 部署之七 (zabbix3.0.4 邮件报警) & 微信报警

    1 [root@sv-zabbix ~]# cat /usr/local/zabbix/share/zabbix/alertscripts/sendEmail.sh #!/bin/bash#SMTP_ ...

  3. 【OS】实模式和保护模式区别及寻址方式

    实模式和保护模式区别及寻址方式 转载请注明出处:http://blog.csdn.NET/rosetta 64KB-4GB-64TB? 我记得大学的汇编课程.组成原理课里老师讲过实模式和保护模式的区别 ...

  4. arguments.callee的用法

    argument为函数内部对象,包含传入函数的所有参数,arguments.callee代表函数名,多用于递归调用,防止函数执行与函数名紧紧耦合的现象,对于没有函数名的匿名函数也非常起作用.举例如下: ...

  5. org.springframework.jdbc.UncategorizedSQLException异常

    用到了mysql的TRUNCATE函数,这个关键字对spring事务有影响,最后换成了ROUND函数

  6. Jquery动态操作checkbox

    问题的由来:html页面中使用checkbox给新建用户授权,然后提交到后台服务器,完成给用户授权.用户授权完成之后,如果用户的权限发生改变管理员需要修改多个用户的权限或查看某用户的权限,点击不同的用 ...

  7. IIS发布网站出现“未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。”的解决方法

    未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序.              说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈 ...

  8. 切换jdk版本

    切换JDK 开发中jdk版本需要是1.3.1,当前电脑中用的是jdk1.8 下载jdk1.3.1 可以在官网上下,但是我捣鼓半天,发现下载又慢又需要账号,所以在CSDN下了个 地址,可以下载第一个ex ...

  9. Socket通讯

    复习贴,资料大多来自百科.看了一遍理解了一遍,把绕口的话按语义给改了`_>` 对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别.不管是Socket还是S ...

  10. Python:函数

    函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 定义和调用 >>> def add(x,y): ... print('x=',x) #Python3必须加&quo ...