通过runtime 动态生成 getter setter

起因

由于oc 的动态性,支持在运行时生成函数,于是想测试下如何生成setter,getter。下方代码是一个简单的例子。

我把 property 声明成了 dynamic ,这样编译器就不会再替我们生成 getter setter ivar了,然后我在运行时动态追加 getter setter ,并测试是否会导致 crash,如果没有出现 unrecognized selector 报错,就成功了。

当然我这只是一个demo,有很多硬编码,真实运用不能这样写,得追加一个NSObject的分类进行全局 hook

源码

//
//  ViewController.m
//  TestDynamicProperty
//
//  Created by zhiyunyu on 2019/6/10.
//  Copyright © 2019年 zhiyunyu. All rights reserved.
//

#import "ViewController.h"
#import "CodeZipper.h"
#import  <objc/runtime.h>

@interface ViewController ()
@property(nonatomic, assign) NSUInteger num;

@end

@implementation ViewController {
    CZ_DYNAMIC_PROPERTYS_FLAG_VAR
    NSUInteger _num;
}

@dynamic num;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // 测试setter
    self.num = 100;
    // 测试getter
    NSLog(@"self.num = %@", @(self.num));
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    NSString *ivarName = @"_num";
    Ivar ivar = class_getInstanceVariable([self class], [ivarName UTF8String]);
    ptrdiff_t offset = ivar_getOffset(ivar);
    
    if (sel == @selector(setNum:)) {
        IMP imp = NULL;
        imp = imp_implementationWithBlock(^(id receive, unsigned long value){
            char *ptr = ((char *)(__bridge void*)receive) + offset;
            memcpy(ptr, &value, sizeof(value));
        });
        class_addMethod([self class], sel, imp, "v@:L");
        return YES;
    } else if (sel == @selector(num)) {
        IMP imp = NULL;
        imp = imp_implementationWithBlock(^(id receive){
            char *ptr = ((char *)(__bridge void*)receive) + offset;
            unsigned long value;
            memcpy(&value, ptr, sizeof(value));
            return value;
        });
        class_addMethod([self class], sel, imp, "L@:");
        return YES;
    }
    
    return [super resolveInstanceMethod:sel];
}

@end


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 面向对象的三大特性:封装、继承、多态 OC内存管理 _strong 引用计数器来控制对象的生命周期。 _weak...
    运气不够技术凑阅读 1,129评论 0 10
  • 设计模式是什么? 你知道哪些设计模式,并简要叙述? 设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型的...
    iOS菜鸟大大阅读 736评论 0 1
  • 1.设计模式是什么? 你知道哪些设计模式,并简要叙述?设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型...
    龍飝阅读 2,192评论 0 12
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,138评论 1 32
  • 开始是什么?开始就像花儿在春天开放;开始就像新生的孩子要学会走路;开始就像大树长出绿芽。而我的开始就是学会做一件小...
    王坤珍惜此时此刻阅读 199评论 0 2