说明
Objective-C Runtime 是什么?
Objective-C 的 Runtime 是一个运行时库(Runtime Library),它是一个主要使用 C 和汇编写的库,为 C 添加了面相对象的能力并创造了 Objective-C。这就是说它在类信息(Class information) 中被加载,完成所有的方法分发,方法转发,等等。Objective-C runtime 创建了所有需要的结构体,让 Objective-C 的面相对象编程变为可能。
OC中一切都被设计成了对象,我们都知道一个类被初始化成一个实例,这个实例是一个对象。实际上一个类本质上也是一个对象,在runtime中用结构体表示
//数据库 —> model1 model2
NSClassFromString
//JSONModel —> cls
//CoreData —> Person
//category —>
//UIViewController
NSLog(@“%@”,[self class])

/// 描述类中的一个方法
typedef struct objc_method *Method;
/// 实例变量
typedef struct objc_ivar *Ivar;
/// 类别Category
typedef struct objc_category *Category;
/// 类中声明的属性
typedef struct objc_property *objc_property_t;
1.消息机制
TQObject *object = [[TQObject alloc] init];
OC的调用方式
[object testFunc];
编译器最终会转换成这样C语言代码去执行
objc_msgSend(object,@selector(testFunc));
2.runtime中的 self和super
//self 是类的隐藏的参数,指向当前当前调用方法的类
//super 并不是隐藏的参数,它只是一个“编译器指示符”它和self指向的是相同的消息接收者
//不同的是,super告诉编译器,当调用setName的方法时,要去调用父类的方法,而不是本类里的
如果是self指针调用的方法 那么 runtime 会自动把发送消息的代码转换成
objc_msgSend(当前消息接收对象, @selector(testFunc));
如果是super指针调用的方法 那么 runtime 会自动把发送消息的代码转换成
objc_msgSendSuper(当前消息接收对象, @selector(testFunc));
3.runtime 遍历一个类中所有的方法和成员变量

4.runtime 动态创建类和方法以及成员
static void myclasstest(id self, SEL _cmd, int a,NSString *name) //self和_cmd是必须的,在之后可以随意添加其他参数
{
Ivar v = class_getInstanceVariable([self class], “testName”);
//返回名为testName的ivar的变量的值
id o = object_getIvar(self, v);
//成功打印出结果
NSLog(@”%@”, o);
NSLog(@”int a is %d %@”, a,name);
}
Class myClass = objc_allocateClassPair([NSObject class], “MyClass”, 0);
//添加成员变量
class_addIvar(myClass, “testName”, sizeof(NSString *), 0, “@”);
class_addMethod(myClass, @selector(myclasstest:), (IMP)myclasstest, “v@:i@”);
//注册这个类到runtime系统中就可以使用他了
objc_registerClassPair(myClass);
id obj = [[myClass alloc] init];
[obj setValue:@”哈哈哈” forKey:@”testName”];
objc_msgSend(obj,@selector(myclasstest:),10,@”hello”);
NSClassFrameString
static void myclasstest(id self, SEL _cmd, int a) //self和_cmd是必须的,在之后可以随意添加其他参数
{
Ivar v = class_getInstanceVariable([self class], “testName”);
//返回名为itest的ivar的变量的值
id o = object_getIvar(self, v);
//成功打印出结果
NSLog(@”%@”, o);
NSLog(@”int a is %d”, a);
}
Class myClass = objc_allocateClassPair([NSObject class], “MyClass”, 0);
//添加成员变量
class_addIvar(myClass, “testName”, sizeof(NSString *), 0, “@”);
class_addMethod(myClass, @selector(myclasstest:), (IMP)myclasstest, “v@:”);
//注册这个类到runtime系统中就可以使用他了
objc_registerClassPair(myClass);
id obj = [[myClass alloc] init];
[obj setValue:@”哈哈哈” forKey:@”testName”];
//调用方法
objc_msgSend(obj,@selector(myclasstest:),10);
5.runtime 给类别增加属性

-(void)setTestName:(NSString *)testName
{
objc_setAssociatedObject(self, testNameKey, testName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)testName
{
return objc_getAssociatedObject(self, testNameKey);
}
模拟简单的JsonModel - RuntimeDemo
ViewController
import objc/runtime.h>
import “TQTestClass.h”
import “TQSubClass.h”
import “TQTestModel.h”
import “TQTestClass+testCate.h”
static void testFunction(id self,SEL _cmd,NSString *name)
{
NSLog(@”%@”,name);
}
@interface ViewController ()
@end
@implementation ViewController
(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.//JSONModel
//self.navigationController
//self super
TQTestClass *testClass = [[TQTestClass alloc] init];//[testClass testFunc];
// objc_msgSend(testClass,@selector(testFunc));
//
// objc_msgSend(testClass, @selector(testFunc:),”zhangsan”);
// TQSubClass *subClass = [[TQSubClass alloc] init];
//
// [subClass testFunc:”“];
// objc_msgSend(subClass, @selector(testFunc:));
pragma mark - 得到当前类中所有的成员变量
if 0
unsigned int varCount = 0;
Ivar *varArray = class_copyIvarList([testClass class], &varCount);for (unsigned int i = 0; i varCount; i++) {
Ivar var = varArray[i];
const char *varName = ivar_getName(var);NSLog(@"%s",varName);
}
NSDictionary *dict = @{@”_testKey1”:@”123456”,@”_testKey2”:@”sdfjglksj”,@”_testKey3”:@”sayiuyiuyioyasiodfy”,@”_testKey4”:@”撒即可法律和”};
TQTestModel *testModel = [[TQTestModel alloc] initWithDict:dict];NSLog(@”%@ %@”,testModel.testKey3,testModel.testKey4);
// NSClassFromString(“myClass”) alloc] init
// Class
//4
//结构体的对其和 补齐
// struct test{
// double a;
// char b; //12
// char b;
// int a;
//
// short c;
};
//继承 和 类别
//NSClassFromString("myClass"
Class MyClass = objc_allocateClassPair([NSObject class], "MyClass", 0);
//增加成员变量 NSString * "@" int "i"
class_addIvar(MyClass, "testName", sizeof(NSString *), 0, "@");
//增加方法
class_addMethod(MyClass, @selector(testFunction:), (IMP)testFunction, "v@:@");
//注册类对象 到 runtime系统
objc_registerClassPair(MyClass);
id obj = [[MyClass alloc] init];
//Ivar
object_setIvar(obj, class_getInstanceVariable([obj class], "testName"), @"zhangsan");
id ret = object_getIvar(obj, class_getInstanceVariable([obj class], "testName"));
objc_msgSend(obj,@selector(testFunction:),@"name");
NSLog(@"%@",ret);
endif
//成员方法
TQTestClass *test = [[TQTestClass alloc] init];
test.testKey = @"zhangsan";
NSLog(@"%@",test.testKey);
}
TQTestClass.m
@implementation TQTestClass
-(void)testFunc
{
NSLog(@”%@”,NSStringFromSelector(_cmd));
}
-(void)testFunc:(char *)name
{
NSLog(@”%@ —> %s”,NSStringFromSelector(_cmd),name);
}
@end
TQTestClass+testCate.m
import objc/runtime.h>
static char *key = “key”;
@implementation TQTestClass (testCate)
-(void)setTestKey:(NSString *)testKey
{
objc_setAssociatedObject(self, key, testKey, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)testKey
{
return objc_getAssociatedObject(self, key);
}
@end
TQSubClass.m
@implementation TQSubClass
-(void)testFunc:(char *)name
{
[super testFunc:name];
//objc_msgSendSuper(struct objc_super *super, SEL op, ...)
//NSLog(@"%@ %@",[self class],[super class]);
}
@end
TQJSONModel.m
import objc/runtime.h>
@implementation TQJSONModel
-(id)initWithDict:(NSDictionary *)dict
{
self = [super init];
if (self) {
unsigned int varCount = 0;
Ivar *varArray = class_copyIvarList([self class], &varCount);
for (unsigned int i = 0; i < varCount; i++) {
Ivar var = varArray[i];
const char *varName = ivar_getName(var);
//String create Table....
//给成员变量赋值
object_setIvar(self, var, dict[[NSString stringWithUTF8String:varName]]);
}
}
return self;
}
@end
TQJSONModel.h
@interface TQTestModel : TQJSONModel
@property (nonatomic,strong) NSString *testKey3;
@property (nonatomic,strong) NSString *testKey4;
@end