iOS

Objective-C之禅学习笔记

2015-07-19  本文已影响472人  阿咿呀嘿

条件语句

条件语句体应该总是用花括号包围起来

不使用Yoda表达式

检查nil和BOOL值时使用感叹号

使用return避免多层嵌套的if语句

复杂的条件表达式提取为BOOL变量

不使用嵌套的三元运算符?:

三元运算符?:的前两个参数相同时应省略第二个参数

对有error引用参数的方法,检查方法返回值而不是error参数,因为有些API可能在返回成功的情况下对error参数写入垃圾值


Case语句

复杂的条件表达式提取为BOOL变量

Case语句包含多行时需要加花括号,单行时不必要

有时可以使用落空fall-through在不同case里执行同一段代码

Switch语句使用可枚举变量时,default是不必要的

定义枚举类型建议使用系统提供的宏NS_ENUM


命名

推荐使用长的、描述性的方法名和变量名

常量使用驼峰命名法,并使用相关类名作为前缀

常量应使用static const声明,不推荐使用#define

需要对外公开的常量,应在头文件中使用extern const声明

对于方法签名,在方法类型(-/+)后加一个空格,方法段之间也加一个空格,参数名称之前应有一个描述性关键字

字面值应该用在任何创建不可变的实例对象情况,特别注意NSArray/NSDictionary中不要放nil,会崩溃的


类名

类名应使用三个大写字母作为前缀(两个字母的为系统类保留)

子类命名时应把描述性部分插入到父类名前缀之后

推荐dealloc方法放在实现文件的最前面,其后是Designated initializer,然后是Secondary initializer

建议所有返回类的实例的类方法、实例方法使用instancetype作为返回类型,而不是id类型

使用类簇Class cluster(即抽象工厂设计模式)减少构造器调用的复杂性,比如NSNumber类

避免使用单例,而应该依赖注入,使用单例要考虑状态更新问题,若必须使用单例,则要用线程安全模式创建共享单例

属性命名尽可能使用描述性文字,避免缩写,小写开头驼峰写法

使用自动同步synthesize,而不是手写@synthesize语句

总是使用getter/setter,但init和dealloc方法中不能使用getter/setter

总使用使用点符号来访问或设置属性

定义属性时,参数排列顺序:原子性、读写、内存管理

使用atomic时,编译器自动添加锁代码,会影响性能,一般使用noatomic

属性可以存储block代码块,使用copy将栈中的block块拷贝到堆中

为了实现一个公开的getter和一个私有的setter,公开属性读写类型设置为readonly,在并在实现文件的扩展中重新定义该属性,读写类型设置为readwrite

如果BOOL属性的名字是描述性的,可以省略is,但需要在getter中指定属性名

任何可以使用可变对象设置的属性,其内存管理类型必须为copy,避免对象在未知情况下被修改

公开属性避免使用可变对象类型,避免破坏封装性,可以通过提供只读属性来返回可变对象的不可变副本

适当使用重载属性的getter方法实现懒加载

对于方法的参数判断最好使用断言NSParameterAssert()来判断参数是否有效,或抛出异常

不要再私有方法名字前天就_前缀,这个前缀是系统保留的

使用isEqual方法判断对象相等性时,要同时实现hash方法,且hash方法不能返回常量

判断对象相等性优先使用isEqualToXXX方法


分类Categories

在类的分类Categories中,方法命名最好增加小写前缀以及下划线,避免不同分类或原类中出现重复的方法名,一旦出现就会导致方法覆盖

使用分类可以在头文件中定义一组功能相似的方法


协议Protocols

Objective-C中使用协议Protocol实现抽象接口

实现协议protocol应该坚持里氏替换原则,即可以取代任意接口实现,而不用改变客户端或相关实现

协议protocol中不但可以声明方法,还可以声明属性


通知NSNotification

通知名称应按照常量的命名规则命名,需要对外暴露的通知,要在公开的接口文档中声明为extern


美化代码

缩进使用4各空格

方法之间空一行

实现文件中声明新起一行

总是冒号对齐


代码组织

GCC、Clang的模糊特性:代码块如果在闭合的圆括号内,块会返回最后一个语句的值,利用这个特性可以组织小块代码

推荐使用#pragma mark -组织代码

使用#pragma clang diagnostic XXX动态修改编译选项

使用#pragma unused(xxx)忽略没有使用变量的编译警告

使用#warning xxx手动生成一个警告

使用#error xxx手动生成一个错误

函数必须有个字符串文档,除非函数是非公开且很短并且显而易见的


对象间的通讯

使用block实现对象之间通讯

把需要提供的数据和错误信息整合到一个单独block中,比分别提供成功和失败的block要好

关于block:block是在栈上创建的,block可以复制到堆上,block拥有自己的私有栈变量的常量复制,可变的栈上德变量和指针必须使用__block关键字声明

委托模式:当事件发生时,委托者需要通知被委托者,名字带Delegate,委托方法的应使用调用方作为第一个参数,返回值为空

数据源模式:委托方需要从数据源对象拉取数据,名字带DataSource,委托方法的应使用调用方作为第一个参数,返回值为需要拉取的数据

委托者在发送消息前需要检查委托是否实现了特定方法

有时可以重载委托方法

使用多重委托而不是滥用NSNotifications


面向切面编程Aspect Oriented Programming

通过切面增加行为:在类的特定方法调用前运行特定代码,在类的特定方法调用后运行特定的代码,增加代码来替代原来的类的方法的实现

参考文档:

https://github.com/objc-zen/objc-zen-book

https://github.com/oa414/objc-zen-book-cn

上一篇下一篇

猜你喜欢

热点阅读