美文网首页
Runtime使用

Runtime使用

作者: 夜雨聲煩_ | 来源:发表于2017-05-19 10:50 被阅读0次

    类与对象操作函数

    runtime有很多的函数可以操作类和对象。类相关的是class为前缀,对象相关操作是objc或object_为前缀。

    类相关操作函数

    name:

    // 获取类的类名
    const char * class_getName ( Class cls ); 
    

    super_class和meta-class:

    // 获取类的父类
    Class class_getSuperclass ( Class cls );
    
    // 判断给定的Class是否是一个meta class
    BOOL class_isMetaClass ( Class cls );
    

    instance_size:

    // 获取实例大小
    size_t class_getInstanceSize ( Class cls );
    

    成员变量(ivars)及属性:

    //成员变量操作函数
    // 获取类中指定名称实例成员变量的信息
    Ivar class_getInstanceVariable ( Class cls, const char *name );
    
    // 获取类成员变量的信息
    Ivar class_getClassVariable ( Class cls, const char *name );
    
    // 添加成员变量
    BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types ); //这个只能够向在runtime时创建的类添加成员变量
    
    // 获取整个成员变量列表
    Ivar * class_copyIvarList ( Class cls, unsigned int *outCount ); //必须使用free()来释放这个数组
    
    //属性操作函数
    // 获取类中指定名称实例成员变量的信息
    Ivar class_getInstanceVariable ( Class cls, const char *name );
    
    // 获取类成员变量的信息
    Ivar class_getClassVariable ( Class cls, const char *name );
    
    // 添加成员变量
    BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types );
    
    // 获取整个成员变量列表
    Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );
    

    methodLists:

    // 添加方法
    BOOL class_addMethod ( Class cls, SEL name, IMP imp, const char *types ); //和成员变量不同的是可以为类动态添加方法。如果有同名会返回NO,修改的话需要使用method_setImplementation
    
    // 获取实例方法
    Method class_getInstanceMethod ( Class cls, SEL name );
    
    // 获取类方法
    Method class_getClassMethod ( Class cls, SEL name );
    
    // 获取所有方法的数组
    Method * class_copyMethodList ( Class cls, unsigned int *outCount );
    
    // 替代方法的实现
    IMP class_replaceMethod ( Class cls, SEL name, IMP imp, const char *types );
    
    // 返回方法的具体实现
    IMP class_getMethodImplementation ( Class cls, SEL name );
    IMP class_getMethodImplementation_stret ( Class cls, SEL name );
    
    // 类实例是否响应指定的selector
    BOOL class_respondsToSelector ( Class cls, SEL sel );
    

    objc_protocol_list:

    // 添加协议
    BOOL class_addProtocol ( Class cls, Protocol *protocol );
    
    // 返回类是否实现指定的协议
    BOOL class_conformsToProtocol ( Class cls, Protocol *protocol );
    
    // 返回类实现的协议列表
    Protocol * class_copyProtocolList ( Class cls, unsigned int *outCount );
    

    version:

    // 获取版本号
    int class_getVersion ( Class cls );
    
    // 设置版本号
    void class_setVersion ( Class cls, int version );
    
    类和函数的使用例子

    通过实例来消化下上面的那些函数:

    //-----------------------------------------------------------
    // MyClass.h
    @interface MyClass : NSObject <NSCopying, NSCoding>
    @property (nonatomic, strong) NSArray *array;
    @property (nonatomic, copy) NSString *string;
    - (void)method1;
    - (void)method2;
    + (void)classMethod1;
    @end
    
    //-----------------------------------------------------------
    // MyClass.m
    #import "MyClass.h"
    @interface MyClass () {
    NSInteger _instance1;
    NSString * _instance2;
    }
    @property (nonatomic, assign) NSUInteger integer;
    - (void)method3WithArg1:(NSInteger)arg1 arg2:(NSString *)arg2;
    @end
    
    @implementation MyClass
    + (void)classMethod1 {
    }
    
    - (void)method1 {
         NSLog(@"call method method1");
    }
    
    - (void)method2 {
    }
    
    - (void)method3WithArg1:(NSInteger)arg1 arg2:(NSString *)arg2 {
         NSLog(@"arg1 : %ld, arg2 : %@", arg1, arg2);
    }
    
    @end
    
    //-----------------------------------------------------------
    // main.h
    
    #import "MyClass.h"
    #import "MySubClass.h"
    #import <objc/runtime.h>
    
    int main(int argc, const char * argv[]) {
         @autoreleasepool {
              MyClass *myClass = [[MyClass alloc] init];
              unsigned int outCount = 0;
              Class cls = myClass.class;
              // 类名
              NSLog(@"class name: %s", class_getName(cls));    
              NSLog(@"==========================================================");
    
              // 父类
              NSLog(@"super class name: %s", class_getName(class_getSuperclass(cls)));
              NSLog(@"==========================================================");
    
              // 是否是元类
              NSLog(@"MyClass is %@ a meta-class", (class_isMetaClass(cls) ? @"" : @"not"));
              NSLog(@"==========================================================");
    
              Class meta_class = objc_getMetaClass(class_getName(cls));
              NSLog(@"%s's meta-class is %s", class_getName(cls), class_getName(meta_class));
              NSLog(@"==========================================================");
    
              // 变量实例大小
              NSLog(@"instance size: %zu", class_getInstanceSize(cls));
              NSLog(@"==========================================================");
    
              // 成员变量
              Ivar *ivars = class_copyIvarList(cls, &outCount);
              for (int i = 0; i < outCount; i++) {
                   Ivar ivar = ivars[i];
                   NSLog(@"instance variable's name: %s at index: %d", ivar_getName(ivar), i);
              }
    
              free(ivars);
    
              Ivar string = class_getInstanceVariable(cls, "_string");
              if (string != NULL) {
                   NSLog(@"instace variable %s", ivar_getName(string));
              }
    
              NSLog(@"==========================================================");
    
              // 属性操作
              objc_property_t * properties = class_copyPropertyList(cls, &outCount);
              for (int i = 0; i < outCount; i++) {
                   objc_property_t property = properties[i];
                   NSLog(@"property's name: %s", property_getName(property));
              }
    
              free(properties);
    
              objc_property_t array = class_getProperty(cls, "array");
              if (array != NULL) {
                   NSLog(@"property %s", property_getName(array));
              }
    
              NSLog(@"==========================================================");
    
              // 方法操作
              Method *methods = class_copyMethodList(cls, &outCount);
              for (int i = 0; i < outCount; i++) {
                   Method method = methods[i];
                   NSLog(@"method's signature: %s", method_getName(method));
              }
    
              free(methods);
    
              Method method1 = class_getInstanceMethod(cls, @selector(method1));
              if (method1 != NULL) {
                   NSLog(@"method %s", method_getName(method1));
              }
    
              Method classMethod = class_getClassMethod(cls, @selector(classMethod1));
              if (classMethod != NULL) {
                   NSLog(@"class method : %s", method_getName(classMethod));
              }
    
              NSLog(@"MyClass is%@ responsd to selector: method3WithArg1:arg2:", class_respondsToSelector(cls, @selector(method3WithArg1:arg2:)) ? @"" : @" not");
    
              IMP imp = class_getMethodImplementation(cls, @selector(method1));
              imp();
    
              NSLog(@"==========================================================");
    
              // 协议
              Protocol * __unsafe_unretained * protocols = class_copyProtocolList(cls, &outCount);
              Protocol * protocol;
              for (int i = 0; i < outCount; i++) {
                   protocol = protocols[i];
                   NSLog(@"protocol name: %s", protocol_getName(protocol));
              }
    
              NSLog(@"MyClass is%@ responsed to protocol %s", class_conformsToProtocol(cls, protocol) ? @"" : @" not", protocol_getName(protocol));
    
              NSLog(@"==========================================================");
         }
         return 0;
    }
    

    输出结果:

    2014-10-22 19:41:37.452 RuntimeTest[3189:156810] class name: MyClass
    2014-10-22 19:41:37.453 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] super class name: NSObject
    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] MyClass is not a meta-class
    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] MyClass's meta-class is MyClass
    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance size: 48
    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _instance1 at index: 0
    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _instance2 at index: 1
    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _array at index: 2
    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _string at index: 3
    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] instance variable's name: _integer at index: 4
    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] instace variable _string
    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] property's name: array
    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] property's name: string
    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] property's name: integer
    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] property array
    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] method's signature: method1
    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] method's signature: method2
    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] method's signature: method3WithArg1:arg2:
    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: integer
    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: setInteger:
    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: array
    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: string
    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: setString:
    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: setArray:
    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] method's signature: .cxx_destruct
    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] method method1
    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] class method : classMethod1
    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] MyClass is responsd to selector: method3WithArg1:arg2:
    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] call method method1
    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] ==========================================================
    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] protocol name: NSCopying
    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] protocol name: NSCoding
    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] MyClass is responsed to protocol NSCoding
    2014-10-22 19:41:37.468 RuntimeTest[3189:156810] ======================================
    

    相关文章

      网友评论

          本文标题:Runtime使用

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