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中得方法比执行中改变更安全
  • 相关阅读:
    【异常】org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter '**' not found.的解决办法
    java如何进行字符串拼接?
    poj2352消防站
    NOIP第7场模拟赛题解
    转载:
    usaco 2010年3月银组题解
    Js 向json对象中添加新元素
    List<T>中 GetRange (int index, int count)的使用
    C# string格式的日期时间字符串转为DateTime类型
    C# DataTable转List<T>--利用反射
  • 原文地址:https://www.cnblogs.com/doudouyoutang/p/4530403.html
Copyright © 2011-2022 走看看