OC语言特性相关

1. 分类-category

  • 如何使用

    1. 声明私有方法
    2. 分解体积庞大的类文件
    3. 把Framework的私有方法公开等
  • 分类的特点(与扩展的区别)

    1. 运行时决议
    2. 可以为系统类添加分类
    3. 可声明,可实现
  • 分类可以添加什么

    1. 实例方法
    2. 类方法
    3. 协议
    4. 属性(只生成get、set方法,不生成实例变量),可添加关联对象
    • 分类添加的方法可以“覆盖”原类的方法
    • 同名分类方法最后被编译的分类最优先生效
    • 命名相同的分类会引起编译错误
  • 分类成员结构


    分类的成员结构
  • 分类的加载调用栈


    QQ20190509-012729@2x

2. 关联对象


id objc_getAssociatedObject(id object, const void *key)


void objc_setAssociatedObject(id object, const void *key, id value, object_AssociationPolicy policy)


void objc_removeAssociatedObject(id object)

关联对象由AssociationsManger管理并在AssociationsHashMap存储。所有对象的关联内容都在同一个全局容器中。

关联对象的本质
QQ20190509-015117@2x

3. 扩展-Extension

  • 使用

    1. 声明私有属性
    2. 声明私有方法
    3. 声明私有成员变量
    • 编译时决议
    • 只以声明的形式存在,多数情况下寄生于宿主类的.m中
    • 不能为系统类添加扩展

4. 代理-Delegate

  • 是一种软件设计模式

    • iOS中以@protocol的形式体现
    • 传递方式一对一
    图解

5. 通知-NSNotification

  • 设计模式 —— 观察者模式
    • 使用观察者模式来实现的用于跨层传递消息的机制
    • 传递方式一对多
通知
  • 实现机制

    通知原理

6. KVO

  • 观察者模式

    • 是Key-value observing的缩写
    • 是OC对观察者模式的又一实现
    • 使用了isa混写(isa-swizzling)来实现
    kvo图解
    • 使用setter方法改变值KVO才会生效
    • 使用setVaule:forKey:改变值KVO才会生效
    • 成员变量直接修改不会生效,可手动触发

7. KVC

  • Key-value coding的缩写

    • Apple 提供的键值编码技术
      • (id)valueForKey:(NSString *)key
      • (id)setValue:(id)value forKey:(NSString *)key
    • 破坏了面向对象编程思想
    访问

    访问顺序

    1. _key
    2. _isKey
    3. key
    4. isKey

    [图片上传失败...(image-bf242a-1557340787646)]

8. 属性关键字

  • 读写权限
    • readonly
    • readwrite(默认)
  • 原子性
    • atomic(默认,保证赋值和获取是线程安全的,如操作并不是线程安全的)
    • nonatomic
  • 引用计数
    • retain/strong
    • assign/unsafe_unretained
      • assign
        • 既可修饰基本数据类型,又可修饰对象
        • 修饰基本数据类型,如int、 BOOL
        • 修饰对象类型时,不改变其引用计数
        • 会产生悬垂指针
    • weak
      • 只能修饰对象
      • 不改变被修饰对象的引用计数
      • 所指对象在被释放后会自动置为nil
    • copy
      • 浅拷贝
        • 增加被拷贝对象的引用计数
        • 没有新的内存分配
      • 深拷贝
        • 产生新的内存分配
        • 不会增加被拷贝对象的引用计数

9. MRC下重写retain修饰变量的setter方法


@property (nonatomic, retain) id obj:

- (void)setObj:(id)obj {
    if (_obj != obj) { // 防止传入同一个变量被释放,后面访问出错
        [_obj release];
        _obj = [obj retain];
    }
}

你可能感兴趣的:(OC语言特性相关)