zoukankan      html  css  js  c++  java
  • Objetive-C +load方法研究

    • load方法的执行时机
              Objetive-C 的runtime会在一个类的所有方法加载到内存中时调用这个类的+load() 方法,因为每个类的方法只是加载一次,所以每个+load()方法只调用一次。
              加载一个类的方法会在一个进程启动开始的时候,这个时候进程的业务代码没有还没有开始执行。
              对于动态库中的类,类的+load方法会在动态库加载进进程的内存空间时的时候执行
     
    • load的执行次序
              +load的方法会从父类到子类的顺序执行,对于一个类的扩展中的Load方法,执行顺序是不确定的。
              +load的方法不遵从其它继承方法执行的规律,只有一个类或者扩展存在load方法的时候才会执行。原因是load的方法的imp查找是直接通过特殊的方法查找的,见
              
    /***********************************************************************
    * _class_getLoadMethod
    * fixme
    * Called only from add_class_to_loadable_list.
    * Locking: runtimeLock must be read- or write-locked by the caller.
    **********************************************************************/
    IMP 
    _class_getLoadMethod(Class cls_gen)
    {
        rwlock_assert_locked(&runtimeLock);
    
        class_t *cls = newcls(cls_gen);
        const method_list_t *mlist;
        uint32_t i;
    
        assert(isRealized(cls));
        assert(isRealized(cls->isa));
        assert(!isMetaClass(cls));
        assert(isMetaClass(cls->isa));
    
        mlist = cls->isa->data()->ro->baseMethods;
        if (mlist) for (i = 0; i < mlist->count; i++) {
            method_t *m = method_list_nth(mlist, i);
            if (0 == strcmp((const char *)m->name, "load")) {
                return m->imp;
            }
        }
    
        return NULL;
    }
    
    
     
     
         下面是一个Demo
     
     
     
    @interface initTest : NSObject
    @end
     
    @interface sub1 : initTest
    @end
     
    @interface sub2 : sub1
    @end
     
    @interface sub2 (category1)
    @end
    @interface sub2 (category2)
    @end
     
     
    //实现
     
    @implementation initTest

    //+(void)initialize
    //{
    //    NSLog(@"%s|%@  ",__func__ ,[self class]);
    //}

    +(void)load
    {
        NSLog(@"%s  ",__func__ );
    }

    @end


    @implementation sub1

    //+(void)initialize
    //{
    //    NSLog(@"%s|%@  ",__func__ ,[self class]);
    //}

    //+(void)load
    //{
    //    NSLog(@"%s  ",__func__ );
    //}
    @end


    @implementation sub2

    //+(void)initialize
    //{
    //    NSLog(@"%s|%@  ",__func__ ,[self class]);
    //}

    +(void)load
    {
        NSLog(@"%s  ",__func__ );
    }

    @end


    @implementation sub2 (category1)

    +(void)load
    {
        NSLog(@"%s  ",__func__ );
    }

    @end

    @implementation sub2 (category2)

    +(void)load
    {
        NSLog(@"%s  ",__func__ );
    }
    @end
     
    执行结果如下:
     
    2015-05-26 13:09:37.955 OCinitTest[79585:72506319] +[initTest load] 
    2015-05-26 13:09:37.956 OCinitTest[79585:72506319] +[sub2 load] 
    2015-05-26 13:09:37.956 OCinitTest[79585:72506319] +[sub2(category1) load] 
    2015-05-26 13:09:37.956 OCinitTest[79585:72506319] +[sub2(category2) load]  
     
    • load方法可以用来做什么
              对于一个方法的Swizzle,因为这个时候改变runtime中得方法比执行中改变更安全
  • 相关阅读:
    遗忘
    2008年第一篇1.15
    键盘对应值
    油田开采基础知识
    最近
    oracle中lob数据的操作
    [转]大数据能做什么,大数据和云是不是一回事?
    [转]从这些方面判断一家公司的好坏
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    谈创新
  • 原文地址:https://www.cnblogs.com/doudouyoutang/p/4530403.html
Copyright © 2011-2022 走看看