美文网首页
Objective-C 的消息发送

Objective-C 的消息发送

作者: yww | 来源:发表于2017-07-26 21:44 被阅读6次

稍微理解一些 Objective-C 的同学都知道, OC 下面调用一个函数, 如[obj somemethod] 其实是一个消息发送的过程, 使用 objc_msgSend(obj, selector) 给对象发送, 当然, 最后还是会设计到找到具体函数执行的过程.
如果你去对某个对象调用一个没有实现的方法, 会报 unrecognized selector 异常. 但是在此之前, 有几次挽救的机会, 我们来看一下这段代码

//
//  main.m
//  MessageSendDemo
//
//  Copyright © 2017年 yww. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface MyObject2 : NSObject
- (void) func3;
- (void) func4;
@end

@implementation MyObject2

- (void) func3 {
    NSLog(@"func3");
}
- (void) func4 {
    NSLog(@"func4");
}

@end

void func2(id self, SEL _cmd) {
    NSLog(@"func2");
}

@interface MyObject : NSObject

- (void) func1;

@end

@implementation MyObject

- (void) func1 {
    NSLog(@"func1");
}

// 第一次尝试
+ (BOOL) resolveInstanceMethod:(SEL)sel {
    if(sel == @selector(func2)) {
        class_addMethod(self, @selector(func2), (IMP)func2, "v@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}
// 第二次尝试
- (id) forwardingTargetForSelector:(SEL)aSelector {
    if(aSelector == @selector(func3)) {
        return [MyObject2 new];
    }
    return [super forwardingTargetForSelector:aSelector];
}
// 第三次尝试
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    if(aSelector == @selector(func4)) {
        return [[MyObject2 new] methodSignatureForSelector:aSelector];
    }
    return [super methodSignatureForSelector:aSelector];
}
-(void)forwardInvocation:(NSInvocation *)anInvocation {
    if(anInvocation.selector == @selector(func4)) {
        [anInvocation invokeWithTarget:[MyObject2 new]];
    }
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        [[MyObject new] func1];
        [[MyObject new] performSelector:@selector(func2)];
        [[MyObject new] performSelector:@selector(func3)];
        [[MyObject new] performSelector:@selector(func4)];
    }
    return 0;
}

我们定义了一个类, MyObject, 里面只有一个 func1 方法. 正常情况下,[[MyObject new] performSelector:@selector(func2)];, [[MyObject new] performSelector:@selector(func3)];, [[MyObject new] performSelector:@selector(func4)]; 这三句都应该会发生unrecognized selector 异常. 可是我们这里对这三个方法进行了处理.
对于 func2, 我们实现了+ resolveInstanceMethod: 方法, 并在这个方法中, 动态增加了一个实例方法func2, 然后返回 YES, 重启消息转发, 最终成功调用到 func2.
对于 func3, 使用了快速转发, 我们实现了-forwardingTargetForSelector: 将 func3 转发给了其他对象处理.
最后的 func4 则是使用了普通转发, 需要实现 -methodSignatureForSelector:-forwardInvocation 也是通过把消息转发给 其他对象来处理, 达到调用 func4 的目的
有兴趣的同学可以看我写的这个 demo https://github.com/ywwzwb/MessageSendDemo

相关文章

  • Objective-C消息发送和消息转发机制

    消息发送 在Objective-C中,使用对象进行方法调用是一个消息发送的过程(Objective-C采用“动态绑...

  • runtime之消息发送与消息转发

    消息发送简介 在Objective-C中,发送消息[receiver message]会被编译器转化为: 如果消息...

  • 深入理解runTime

    Objective-C Runtime 引言 Objective-C的方法调用实则为“发送消息”,我们来看[dog...

  • objective-c中如何直接调用objc_msgSend

    在Objective-C中,函数的调用最终都会转为成消息发送,objc_msgSend即为这个负责消息发送的函数。...

  • 2018-02-01

    《Objective-C runtime系列 1》消息发送及转发机制 Objective-C是基于C,加入了面...

  • Objective-C消息发送

    一 概述:Objective-C(简称OC)的Cocoa层的API中有大量的[receiver message]消...

  • Objective-C 消息发送

    都知道 OC 是一门动态语言,其动态的特性归根结底就是runtime,消息发送。所有的方法在经过runtime 时...

  • Objective-C 的消息发送

    稍微理解一些 Objective-C 的同学都知道, OC 下面调用一个函数, 如[obj somemethod]...

  • 与Runtime相关的知识

    网上的知识很多,但是知识只有自己过一遍才有意义。 关于消息发送和消息转发,Objective-C 消息发送与转发机...

  • objc-msg-arm64源码深入分析

    在 Objective-C 语言中,实例对象执行方法,而执行方法的过程也可以称为给实例对象发送消息。发送消息的过程...

网友评论

      本文标题:Objective-C 的消息发送

      本文链接:https://www.haomeiwen.com/subject/nsnnkxtx.html