Effective OC(读后感)

1、对象内部尽量直接访问实例变量

  • 直接访问实例变量不会进行方法派发,直接访问对应内存(读直接用实例变量,写为了调试可以使用属性)
  • 直接访问实例变量不会触发KVO

2、判断两个对象,或者两个值是否相等

1、== 能判断不管对象还是基础类型是否相等。基础类型比较的是值内容,对象比较的是指针是否相同(NSString 比较独特,因为字符串驻留的优化技术,所有的字符串都是在一个共享字符串池中的,将不可变字符串的值赋值给了不同的指针.)
2、等同性判断:-isEqual方法和-hash方法
3、通过增加唯一标识符来减少执行深度
4、容器中的可变类等同性不可控

3、关联(一般用于类扩展中增加属性)

4、运行时

==运行时有一些机制,其中最主要的是消息机制。消息机制就是在运行时才能确定调用的是哪个函数==

  1. 交换方法(可以用于调试日志打印)
  2. 动态添加方法performSelector
  3. 给分类添加属性
  4. 字典转模型,模型转字典

5、消息转发机制

两个阶段:1.动态方法解析;2、完整的消息转发机制

graph LR
+resolveInstanceMethod-->class_addMethod
class_addMethod-->forwardingTargetForSelector
forwardingTargetForSelector-->forwardInvocation

6、调试方法“黑盒方法”

graph LR
class_getInstanceMethod-->method_exchangeImplementetions

7、全能初始化方法

  1. 如果子类的全能初始化方法与超类方法的名称不同,需要覆写超类的全能初始化方法
  2. 提供一个全能初始化方法,其他初始化方法调用他
  3. 子类不适用超类初始化方法则覆写抛出异常

8、尽可能使用不可变对象

  1. 尽可能创建不可变的对象
  2. 若某属性仅可对于对象内部修改,则在分类中将其readonly改为readwrite
  3. 不要把可变的collection作为公开属性

9、oc错误模型

  • NSError返回有两种方式
  1. 通过代理用NSError *error参数返回(代理传值)
  2. 由输出参数返回给调用者NSError **error
int a 做参 a值不会变
int *a  做参 *a值不会变,a会变
int **a 做参 **a值不会变,*a会变,a会变

10、深浅拷贝

  1. copy出来的字符串一定是不可变字符串,如果传入的是可变字符串,会发生深拷贝为不可变字符串,否则为浅拷贝
  2. mutablecopy,一定是深拷贝,拷贝出来的一定是可变字符串或者数组,即使传入的是不可变字符串或者数组
  3. 对于集合类的可变对象来说,深拷贝并非严格意义上的深复制,只能算是单层深复制,即虽然新开辟了内存地址,但是存放在内存上的值(也就是数组里的元素仍然之乡员数组元素值,并没有另外复制一份),这就叫做单层深复制
  4. 集合对象的完全深拷贝
//归解档
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:marry1];
    NSArray *marray2 = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:nil];
    
//深拷贝函数
- (instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag;

11、通过委托与数据源进行对象间的通信

  • 委托用于本体与雇主进行通信,让雇主完成本体无法完成的动作
  • 数据源用于本体从雇主那边获取最新的数据
  • 可以使用位段的结构体,将委托对象是否响应相关协议方法进行缓存,不用每次都执行判断函数

12、分类

  • 分类必须引入头文件
  • 最好不要在分类中声明属性
  • 使用class-continuation分类隐藏实现细节(可以将readonly属性修改为readwrite)

13、通过协议提供匿名对象

id obj

你可能感兴趣的:(Effective OC(读后感))