Runtime介绍 + 模拟简单的JSONModel

说明

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;

扫描二维码关注公众号,回复: 3797956 查看本文章

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

猜你喜欢

转载自blog.csdn.net/weixin_35966617/article/details/53097339