IOS中的编码规范
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中的编码规范的更多相关文章
- [iOS翻译]Cocoa编码规范
简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...
- iOS中书写代码规范35条小建议
1.精简代码, 返回最后一句的值,这个方法有一个优点,所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染.但缺点是可读性比较差 NSURL *url = ({ ...
- 直播二:iOS中硬编码(VideoToolBox)
硬编码相对于软编码来说,使用非CPU进行编码,如显卡GPU.专用的DSP.FPGA.ASIC芯片等,性能高,对CPU没有压力,但是对其他硬件要求较高(如GPU等). 在iOS8之后,苹果开放了接口,并 ...
- ios中base64编码
参考文章:其中文章的:http://blog.csdn.net/ztp800201/article/details/9470065 下载包 其中 包括GTMBase包下载地址 http://pan.b ...
- IDEA中FindBugs编码规范工具使用
IDEA中安装FindBugs插件: file--Settings--Plugins 在Plugins搜索FindBugs: 安装完成后在项目中选中文件右键找到findBugs: 检查代码结果: 按照 ...
- PHP编码规范PSR-2
.note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...
- 标准的Java编码规范手册
编码规范体现出一个开发者的基本素质,良好的编码规范可以提高团队编码的效率,避免很多不必要的问题.今天分享一个标准的Java编码规范给大家,希望对于大家今后的开发工作带来帮助. 编码规范的意义 ...
- 浅谈 JavaScript 编程语言的编码规范
对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...
- Discuz代码研究-编码规范
Discuz中的编码规范很值得PHP开发人员借鉴.里面既介绍了编码时代码标记,注释,书写规则,命名原则等方面基础的内容,对代码的安全性,性能,兼容性,代码重用,数据库设计,数据库性能及优化作了阐述,这 ...
随机推荐
- MFC编程入门之二十三(常用控件:按钮控件的编程实例)
上一节讲了按钮控件Button.Radio Button和Check Box的基本用法,本节继续讲按钮控件的内容,通过一个实例让大家更清楚按钮控件在实际的软件开发中如何使用. 因为Button控件在前 ...
- 转:在java中使用dom4j解析xml
JAVA 使用Dom4j 解析XML Java DOM4J Parser - Parse XML Document Dom4j下载及使用Dom4j读写XML简介 在java中使用dom4j解析xml ...
- SQL Server Reporting Service(SSRS) 第三篇 SSRS Matrix用法
以前不是太清楚SSRS的功能,自从最近有了了解之后,发现它的功能的确很强大.对于Matrix,刚开始我竟不知道它到底有什么用,现将通过一个例子中去理解Matrix,以及和分组Group结合使用的便利性 ...
- 转载:Maven项目mybatis Invalid bound statement (not found)解决方法
在mapper代理的开发中,程序员需要遵守一些规范,mybatis才能实现mapper接口的代理对象. 它的规范如下: mapper.xml的namespace要写所映射接口的全称类名. mapper ...
- es5 and es6
es5学习地址:http://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9 ...
- Access使用join进行多个表联合查询的问题
Access是支持三表或三表以上的join查询的,但是要加括号,如果不加的话,会报错,括号的作用是决定join的顺序.例如: SELECT *FROM (aa LEFT JOIN bb ON aa.a ...
- 解决:Redis:java.util.NoSuchElementException: Unable to validate object at
在Java使用Redis的过程中遇见了一个问题, redis.clients.jedis.exceptions.JedisConnectionException: Could not get a re ...
- DEVExpress GridControl|TableView |FormatConditions 按一定格式设置相应内容
Get到一个新技能,感觉好棒.摘自DEV官网:https://www.devexpress.com/Support/Center/Example/Details/T135593 <Window ...
- zencart産品描述加上錨文本
首先,函數會遍曆整段描述,假如一段描述裏面有Hermes wallets這個關鍵詞,那麽函數就會對這個關鍵詞加上鏈接,至于鏈接到哪裏,上面數組裏面有,隻要把數組裏面的内容替換你想要的就可以. 那麽在z ...
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
本文由CocoaChina译者lynulzy(社区ID)翻译 作者:Bohdan Orlov 原文:iOS Architecture Patterns 在 iOS 中使用 MVC 架构感觉很奇怪? 迁 ...