iOS Runtime之动态创建类

场景

当遇到一些在App中没有创建过的类,想要动态添加时,可以使用。
例如:云端控制点击响应页面跳转事件。

应用

动态创建类,开辟内存

objc_allocateClassPair可以动态创建类,指示它的父类。
class_addIvar可以给类添加成员变量。
objc_registerClassPair注册一个已经创建的类,在添加成员变量后使用。
class_addMethod给类添加方法。

实现

#import "JX_DynamicClassViewController.h"
#import <objc/runtime.h>

@interface JX_DynamicClassViewController ()

@end

@implementation JX_DynamicClassViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn setTitle:@"Go" forState:UIControlStateNormal];
    [btn setBackgroundColor:[UIColor blackColor]];
    [btn setFrame:CGRectMake(10, 100, 200, 40)];
    [btn addTarget:self action:@selector(newPageClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
}

// 按钮点击
- (void)newPageClick {
    // 动态创建一个vc,开辟内存
    Class cls = objc_allocateClassPair(UIViewController.class, "JX_DynamicVC", 0);
    
    // 给vc添加变量
    class_addIvar(cls, "bgColor", sizeof(UIColor *), log2(sizeof(UIColor *)), @encode(UIColor *));
    class_addIvar(cls, "text", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
    objc_registerClassPair(cls);
    
    
    // 给vc添加方法
    IMP vdl_imp = class_getMethodImplementation([self class], @selector(viewDidLoad_dynamicImp));
    class_addMethod(cls, @selector(viewDidLoad), vdl_imp, "v16@0:8");
    // 方法签名不想手写,也可以通过方法获取
//    const char *types = method_getTypeEncoding(class_getInstanceMethod([self class], @selector(viewDidLoad_dynamicImp)));
//    class_addMethod(cls, @selector(viewDidLoad), vdl_imp, types);
    
    // 初始化新类对象
    id newVC = [[cls alloc] init];
    [newVC setValue:[UIColor greenColor] forKey:@"bgColor"];
    [newVC setValue:@"this is dynamic vc" forKey:@"text"];
    [self presentViewController:newVC animated:YES completion:^{
            
    }];
}

// 动态创建vc的viewDidLoad方法实现
- (void)viewDidLoad_dynamicImp {
    [super viewDidLoad];
    // 这里方法因为添加给newVC,因此self是newVC
    [self setValue:[self valueForKey:@"bgColor"] forKeyPath:@"view.backgroundColor"];
    // 添加标签
    UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(10, 200, 200, 40)];
    [[self valueForKey:@"view"] addSubview:lab];
    lab.text = [self valueForKey:@"text"];
}
@end

其他

没有其他了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xinxin_0

带我喝杯茶~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值