Effective Objective-C 2.0读书笔记 (一)

Effective Objective-C 2.0读书笔记 

编写高质量的iOS和OS X的52个有效方法

第1条,Objective-C语言的起源

  • Objective-C 是C语言的超集(拓展 Extensions 或补充),增加了面向对象特性。大量使用方括号、方法名长,属于消息结构的语言(运行执行的代码由运行环境决定,非编译器;运行执行的函数,不论是否多态,运行时才去查找对应方法,即动态绑定),有点类似路由器,起到中间件作用。
  • OC的重要工作都是由“运行期组建”完成。“运行期组建”:数据结构、函数(内存管理方法)、动态库、提升应用性能。
  • OC的内存模型和“引用计数”机制的工作原理很重要。OC的对象在内存分配上:指针放栈上,对象实际内存放堆空间里。非对象变量(不含*)直接放栈空间;非对象类型(int、float、double、char)放栈空间。

关键词:C语言超集、面向对象、消息型结构、动态执行

第2条,类头文件中尽量少引用其他头文件

  • OC类创建后有两个文件:头文件后缀为.h,实现文件后缀为.m。
  • 在头文件中声明其他类作为属性的时候,引用其他类的头文件这种方式可行,但是影响性能。因为编译器会将引用的类全部细节扫描一边,浪费了编译时间,替代方式为:向前声明(@class XXXX类),达到既可以用,又不用扫描细节,起到了占位作用。
  • 实现文件中,如果使用其他类,则需要引入其他类的头文件。
  • 在两个类的头文件相互引用对方,会导致循环引用问题,OC用 “#import”不是“#include”指令不会导致死循环发生,但是会让其中一个类的无法正确编译。
  • 头文件不得不引用情况:继承超类(直接引用)、声明协议(要么放到分类中;要么放单独头文件中再引用)。

目的:减少不必要的编译时间;降低了类之间的耦合度,增加了鲁棒性(外来词 Robustness:健壮性、稳健性、强健性)。

关键词:头文件、实现文件、向前声明、类引用

第3条,多用字面量语法,少用与之等价的方法

  • 字面量语法是一种语法糖(计算机语言中,与另外一套语法【通常指常规语法】等效,但是用起来更方便的语法称为语法糖)。俗气点的说法:捷径语法、特权语法、开小灶语法…
  • 使用字面量语法来创建字符串、数值、数组、字典,比常规语法更简单明了。
  • 字面量语法下的数组可以直接用下标,字典键值对应关系直观。字面量语法下的数组和字典中有值有nil会抛出异常,需确保值不为nil。

目的:缩减代码长度,易读;整洁,精简;更安全,能在nil时抛异常

关键词:语法糖、字面量语法、数值、字典

第4条,多用类型常量,少用#define预处理指令

  • 常量添加类型信息,有助于描述常量的含义。实现文件( .m)内的常量以k开头;常量对类外可见的话,以类名为前缀,用const来修饰,加上extern外部符号。
  • 不要用预处理指令来定义常量,这样定义的常量不含类型信息。
  • 实现文件中使用static const 定义只在该实现文件范围内可见的常量。
  • 头文件中使用extern 声明全局常量,加类名作为前缀,在实现文件里定义值。

目的:减小常量的影响范围,防止常量被相互污染

关键词:预处理指令define、类型常量、static、const、extern

第5条,枚举表示状态、选项、状态码

  • 枚举是一种常量命名方式。编译器会为枚举分配独有的编号,默认从0开始,每个枚举递增1。
  • 在定义枚举变量的时候,为了不用每次都敲入enum,在enum之前加上typedef关键字即可。
  • 定义选项的时候,如果多个选项可以彼此组合,那么可以枚举类型的二进制形式,通过逻辑位运算操作来相互组合。
  • 枚举定义在系统中分为NS_ENUM和NS_OPTIONS,如果枚举有组合操作则选NS_OPTIONS,如果枚举唯一互斥则选NS_ENUM。
  • switch语句中,使用枚举定义状态机的时候,不要在最后加上default,确保switch处理状态正确。

关键词:枚举、typedef、枚举选项组合、逻辑运算、位运算、switch中的枚举

第6条,理解“属性”这一概念(重点)

  • 属性用于封装对象中的数据,写用set,存用get。
  • 类中新增实例变量,OC做法是把实例变量当做一种存储偏移量所用的特殊变量,交给类对象保管,只有在运行期需要用的时候才去根据实例变量去查找对应内存的偏移量。
  • OC根据@property 语法来自动创建属性的存取方法。
  • 可以使用点语法来访问类的属性。
  • 编译器会在属性使用的时候,自动编写访问这些属性所需的方法(set、get),并在类中添加在属性名前加下划线的新实例变量名,如果对系统生成的变量名不满意还可以通过@synthesize语法来自定义变量名。通常建议不修改。
  • 如果不想编译器自动生成(set、get)方法,可以用@dynamic 语法进行阻止。
  • 属性的特质分为四类:原子性、读/写权限、内存管理语义、方法名。
  • 属性的原子性(atomic)和非原子性(nonatomic):属性的原子性本质上就是在set/get方法里加锁,对值起保护作用,但是多线程中不能确保业务值安全(Atomic is really commonly confused with being thread-safe, and that is not correct. You need to guarantee your thread safety other ways.-摘自realm)。非原子属性不进行变量的值保护,少了锁保护,性能提升。
  • 属性的读写权限:readwrite和readonly,由@systhesize 实现的时候,前者编译器自动生成set/get方法,后者只生成get方法。
  • 属性的内存管理标记:assign、strong、weak、unsafe_unretained、copy。
  • assign :基础数据类型 (NSInteger,CGFloat)和C数据类型(int、float、double、char等等)。存储在栈内存,没有引用计数。如果修饰普通对象,在对象被堆内存释放后,指针地址还在,成为了野指针,后期指针指向的内存重新被分配的时候会造成崩溃。
  • strong:表示属性定义了拥有关系,是一种强引用,会增加引用计数,为属性设置新值的时候,会先保留新值,后释放旧值,然后赋值新值。
  • weak:表示属性定义了非拥有关系,是一种弱引用,不会增加引用计数,为属性设置新值的时候,不保留也不释放旧值,属性的对象遭销毁的时候,属性值会清空。
  • unsafe_unretained:与assign相同,但适用对象类型,定义非拥有关系,当对象销毁时,属性值不会跟着清空。
  • copy:最常见声明的是NSString,保护其封装性,设置方法不保留新值,而是拷贝。
  • copy拓展:浅拷贝和深拷贝。深浅拷贝取决于拷贝后的对象是不是和被拷贝对象的地址相同,如果不同,则产生了新的对象,即为深拷贝。如果不同,则只是指针拷贝,相当于retain一次原对象,即为浅拷贝。
  • copy与mutableCopy:copy复制后的对象是不可变对象,mutableCopy复制后的对象是可变对象,与原始对象是否可变无关。对不可变对象执行copy操作,是指针复制(浅拷贝),执行mutableCopy操作是内容复制(深拷贝);对可变对象执行copy操作和mutableCopy操作都是内容复制(深拷贝)。容器对象和非容器对象类似,可变对象复制的都是一个新对象,不可变对象copy的是浅复制,mutableCopy是深复制;对于容器而言,元素对象始终是指针复制。

关键词:property、点语法、synthesize、dynamic、atomic、nonatomic、readwrite、readonly、assign、strong、weak、unsafe_unretained、copy、mutableCopy

原文地址:https://www.cnblogs.com/akiha/p/13267905.html