美文网首页
编写高质量iOS代码读书笔记二

编写高质量iOS代码读书笔记二

作者: crazyfox | 来源:发表于2017-09-26 15:30 被阅读15次

第二章.对象,消息,运行时

6.理解“属性”这一概念

-可以用@property语法来定义对象中所封装的数据
-通过特质来指定存储数据所需的正确语义

属性的attribute分为四种
-原子性nonatomic,atomic,
-读写权限readWrite,readonly
-内存管理语义
1.assign "设置方法"只会执行针对基础类型的简单赋值操作
2.strong 此特质表明该属性定义了一种“拥有关系”。为这种属性设置新值时,设置方法先保留新值,并释放旧值,然后再将新值设置上去。
3.weak 此特质表明该属性定义了一种“非拥有关系”。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质与assign类似,然而在属性所指的对象遭到摧毁时,属性值也会清空nil。
4.unsafe_unretained 此特质的语义和assign相同,但是它适用于“对象类型”,该特质表达一种“非拥有关系”,当目标对象遭到摧毁时,属性值不会自动清空。
5.copy 此特质的语义和strong类似。然而设置方法不保留新值,而是将其copy。
-方法名
getter=<name> setter = <name>

-在设置属性所对应的实例变量时,一定要遵从该属性所声明的语义
-开发iOS程序时应该使用nonatomic属性,atomic属性会严重影响性能

7.在对象内部尽量直接访问实例变量 P29区别

-在对象内部读取数据时,应该直接通过实例变量来读,而写入数据时,则应该通过属性来写。
-在初始化方法及dealloc方法中,总是应该直接通过实例变量来读写数据
-有时会使用惰性初始化技术配置某份数据,这种情况需要通过属性来读取数据

8.理解“对象等同性”这一概念

==比较的是两个指针 isEqual比较的是指针对应的对象
-若想检测对象的等同性,请提供"isEqual:"与hash方法
-相同的对象必须具有相同的哈希码,但是两个哈希码相同的对象却未必相同。
-不要盲目的逐个检测每条属性,而是应该依照具体需求来制定检测方案
-编写hash方法时,应该使用计算速度快而且哈希码碰撞几率低的算法

推荐的哈希算法
-(NSUInteger)hash{
NSUInteger firstNameHash = [_firstName hash];
NSUInteger lastNameHash = [_lastName hash];
NSUInteger ageHash = _age;
return firstNameHashlastNameHashageHash;
}

9.以“类族模式”隐藏实现细节

-类族模式可以把实现细节隐藏在一套简单的公共接口后面
-系统框架经常使用类族
-从类族的公共抽象基类中继承子类时要当心

10.在既有类中使用关联对象存放自定义数据

OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
-可以通过“关联对象”机制来把两个对象连起来
-定义关联对象时可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”和“非拥有关系”
-只有在其他做法不可行时才应选用关联对象

11.理解objc_msgSend的作用

OC传递消息,用动态绑定的方式来决定调用的方法
id returnValue = [someObj messageName:param];
编译器将他转化为 C语言函数,调用的是消息机制的核心方法
id returnValue = objc_msgSend(someObj,@selecter(messageName:),param)
objc_msgSend函数会在someObj对象中查找messageName方法,如果没有就在父类中找,如果还没有,跳到转发机制
执行过的方法会放在obj对应的方法缓存列表,以便下次调用能快速查找

12.理解消息转发机制

对象接收到无法解读的消息之后,调用

  • (BOOL)resolveClassMethod:(SEL)sel
  • (BOOL)resolveInstanceMethod:(SEL)sel
    重写此方法,可以新增一个处理消息的方法
    如果没有设置
    调用
  • (id)forwardingTargetForSelector:(SEL)aSelector
    返回能处理消息的其他对象
    如果没有对象返回,
    调用
  • (void)forwardInvocation:(NSInvocation *)anInvocation
    创建NSInvocation对象,指定消息的调用对象
    如果还没有处理,调用
  • (void)doesNotRecognizeSelector:(SEL)aSelector;
    抛出异常

13.用“方法调配技术”调试“黑盒方法”

OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2)
方法替换

14.理解“类对象”的用意

-每个实例都有一个指向Class对象的指针,用以表明其类型,而这些Class对象则构成了类的继承体系
-如果对象类型无法在编译期确认,就该用类型信息查询方法探知
-尽量使用isKindOfClass,isMemberOfClass来确认对象类型,不要直接比较类对象,因为可能实现了消息转发

相关文章

网友评论

      本文标题:编写高质量iOS代码读书笔记二

      本文链接:https://www.haomeiwen.com/subject/mckjcxtx.html