美文网首页
iOS 分类(category)的高级详解

iOS 分类(category)的高级详解

作者: 孙掌门 | 来源:发表于2019-12-13 11:17 被阅读0次

    iOS 分类(category)的高级详解

    作用

    1.可以声明一些私有方法,如做SDK一些接口不想暴露给别人看,想自己内部使用,可以通过私有方法,自己内部使用,反过来也可以公开自己的framework中的一些方法给别人看,当没有公开的时候,可以通过加一个分类将私有方法公开。

    2.分解体积庞大的类文件,同一功能放到一个 category 中。

    3:可以为系统类添加分类,如最常见的 UIView分类,来或得x,y,w,h等

    特点

    1.运行时决议,编译好分类之后,并没有把方法添加到宿主类上面,运行时添加到宿主类上面

    分类中可以添加哪些内容

    1.实例方法

    2.类方法

    3.协议

    4.属性(只生成set和get方法,并没有生成实例变量,通过关联对象可以添加实例变量,因为底层的category_t 结构体里面,只存名字实例方法,类方法,协议等信息,没有存实例变量的)

    分类调用栈

    分类倒序遍历,最先访问最后编译的分类,分类有多个,最后编译的分类的方法会生效

    分类添加的方法可以“覆盖”原来类的方法,因为在runtime源码中,有memmove,会把分类中的方法移动到原来类方法的前面,所以会执行分类中的方法,因为有方法选择器,当匹配到了分类中的方法之后,就会执行,分类中的方法,但原来类的方法依然存在。

    同名分类方法谁能生效取决于编译顺序,最后被编译的分类,会最先生效

    名字相同的分类会引起编译报错

    为分类添加实例变量

    可以通过关联对象的方式为分类添加成员变量,objc_getAssociatedObjc , objc_setAssociatedObject,通过关联对象为原来添加成员变量,并没有添加到宿主类上面,关联对象由 AssociationManager 管理并在 AssociationsHashMap 中,所有对象的关联内容都在同一个全局容器中,为不同的类添加也都在一个全局容器中。在runtime源码中,创建一个对象的时候,会先判断值是否为空,如果为nil,那么就证明将之前设置的值移除掉,如果不为空,会先判断,是否能找到 ObjcAssociationMap,如果没有找到会创建一个map,如果找到了,会用新的值替换掉原来map中的值,大概可以描述为下面的 json 形式

    /*
         加入下面是为某个类添加的成员变量
         */
        
        {
            /*
             类1:
             @property(copy)NSString *name;
             */
            // 类1
            // 最外面的 key 为被关联的对象,value 是一个 ObjcAssociationMap ,ObjcAssociationMap 中,@selector 为被关联的值得 key,policy 为策略,是 retain还是copy 等
            "0x1242342432":{
                "@selector(name)":{
                    "value":"sunchengxiu",
                    "policy":"copy"
                }
            },
            // 类2
            "0x54354253223":{
                
                "@selector(age)":{
                    "value":"25"
                    "policy":"retain"
                }
            }
        }
        
    
    

    相关文章

      网友评论

          本文标题:iOS 分类(category)的高级详解

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