提升

objc_msgSend()新版本使用

2019-04-12  本文已影响0人  it_Xiong

很久没有研究runtime方面的知识了,最近在总结下KVO,自己实现一个KVO的过程中,发现objc_msgSend()函数发送消息不能传参,刚好把自己的解决办法分享出来。

objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)
objc_msgSend(void /* id self, SEL op, ... */ )

没有参数了肿么办,我就是要传参数啊,不然调用它干嘛...
个人认为内部依然还是存在这两个参数, 于是去rumtime源码里查看,runtime的苹果源码可以去苹果官网上下载👉runtime源码
后面发现将这个函数看成c语言的函数声明,通过强制转化类型解决这个问题,这个是runtime源码里面的:

objc01.png

也可以像下面这样:

((void(*)(id,SEL,NSString *))objc_msgSend)(self,@selector(setName:),newName);

或者这样:

     ((void (*)(id, SEL,NSString*,id, NSDictionary<NSString*,id>*,void *))objc_msgSend)(observer, @selector(observeValueForKeyPath:ofObject:change:context:),@"name",self,@{@"name":newName},nil);

当然也可以直接转化为新的函数,更加容易调用,例如下面这样:

  id (*function1)(id, SEL, void(^)(NSString* a, NSInteger b)) = (id (*)(id, SEL, void (^)(NSString* a,NSInteger b)))objc_msgSend;

  id (*function2)(id, SEL, NSString *) = (id (*)(id, SEL, NSString *))objc_msgSend;

使用起来就比较方便:

 function1(self,@selector(setName:),^(NSString* a,NSInteger b){
        
        NSLog(@"%@%ld",a,(long)b);
    });

 function2(self,@selector(setName:),newName);
上一篇 下一篇

猜你喜欢

热点阅读