Runtime使用

类与对象操作函数

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 
@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 

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使用)