美文网首页
OC方法设置的效率

OC方法设置的效率

作者: 迷路的字母C | 来源:发表于2021-12-02 11:07 被阅读0次

    OC中method_setImplementation和method_exchangeImplementations,由于涉及到类方法缓存的清理问题,需要对某一个类的所有子类进行方法缓存清理。但是这两个方法的默认实现是从根类开始遍历,也就是说,如果使用了这两个方法,那么runtime会遍历整个类树,执行方法缓存清理,rumtime工作量很大。

    IMP 
    method_setImplementation(Method m, IMP imp)
    {
        // Don't know the class - will be slow if RR/AWZ are affected
        // fixme build list of classes whose Methods are known externally?
        mutex_locker_t lock(runtimeLock);
        return _method_setImplementation(Nil, m, imp);
    }
    
    static IMP 
    _method_setImplementation(Class cls, method_t *m, IMP imp)
    {
        // 此处省略无关代码
    
        // Cache updates are slow if cls is nil (i.e. unknown)
        // RR/AWZ updates are slow if cls is nil (i.e. unknown)
        // fixme build list of classes whose Methods are known externally?
    
        flushCaches(cls, __func__, [sel, old](Class c){
            return c->cache.shouldFlush(sel, old);
        });
    
        // 此处省略无关代码
    }
    
    void method_exchangeImplementations(Method m1, Method m2)
    {
    
        // 此处省略无关代码
    
        // RR/AWZ updates are slow because class is unknown
        // Cache updates are slow because class is unknown
        // fixme build list of classes whose Methods are known externally?
    
        flushCaches(nil, __func__, [sel1, sel2, imp1, imp2](Class c){
            return c->cache.shouldFlush(sel1, imp1) || c->cache.shouldFlush(sel2, imp2);
        });
    
        // 此处省略无关代码
    }
    

    两个方法最终都是使用了flushCaches实现,该方法在未传入cls的情况下,会从NSObject开始遍历,会遍历所有的类,苹果文档里面的备注也说明了这一点

    static void flushCaches(Class cls, const char *func, bool (^predicate)(Class))
    

    虽然在遍历的过程中,有了根据缓存判断,需不需要清理的过程,但是如果项目中的类过多,每次设置,效率还是很低下的。

    相关文章

      网友评论

          本文标题:OC方法设置的效率

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