条件语句
条件语句体应该总是用花括号包围起来
不使用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
网友评论