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

Objective-C消息发送

作者: Hunter琼 | 来源:发表于2018-03-26 10:02 被阅读59次

一 概述:
Objective-C(简称OC)的Cocoa层的API中有大量的[receiver message]消息发送机制,初学时我们往往把理解为一个object调用了一个method,而往往忽视了"消息机制"这句话的深刻含义,[receiver message]独特机制区别于其他主流语言,这也是很多软件开发者转型iOS 选择Swift原因了.
二 原理:
消息发送机制是Runtime通过selector快速查找IMP的过程,有了IMP这个函数指针,就可以执行对应的方法实现.
[receiver message]会被编译器转换成为:

// arg1 ,arg2... 表示消息含有的参数
objc_msgSend(receiver, selector, arg1, arg2, ...)

如果消息的接受者能够找到对应的selector,相当于执行了这个对象方法,否则消息要么被转发,要么临时向接受者动态添加这个 selector 对应的实现内容,要么就干脆崩溃

IMP:定义为 typedef void (*IMP)(void /* id,SEL,... */);本质是个函数指针,由编译器生成,当发送一条消息之后,最终它会执行方法,就是由该函数指针定的,而IMP这个函数指针就是指向了这个方法的实现.
三 super
super是OC的保留字,不是隐式参数,它只是个''编译器指示器',主要是针对父类
id objc_msgSendSuper(struct objc_super *super,SEL op,...)
当消息传递给父类的时候,调用objc_msgSendSuper,objc_super 这个结构体会存放当前函数里的self(隐式参数)的super_class,即[self superclass];msgSendSuper从当前对象的父类方法开始,沿着父类继承链查找.最终执行到[super respondsToSelector:@selector(superHasNotThisSelector) ]; 而respondsToSelector这个方法是NSObject方法,而NSObjcet类位于所有类继承的顶端,执行这个方法会找到对应的实现函数!
四 self
self是OC的隐式参数,之所以叫隐式参数是因为源代码方法定义中并没有声明这个参数,但我们可以引用它;self本身也是个指针,在每个方法中都有一个self指针,在函数中无法使用,可以使用self -> 成员变量
五 动态方法
前面提到某些情况下消息的接受者无法找到对应的selector时,会临时向接受者动态添加这个selector对应的实现内容.
给某个属性声明@dynamic类型,编译器会认为这个属性相关的方法会动态提供,也就是说编译器不会默认生成属性的setget方法了,而需要我们动态提供,可以通过重载resolveInstanceMethod:resolveClassMethod添加动态方法.
代码示例如下:

#import <Foundation/Foundation.h>

@interface AutoMehtodModel : NSObject
@property(nonatomic,copy)NSString *addAutoMethod;

@end
#import "AutoMehtodModel.h"
#import <objc/runtime.h>
@implementation AutoMehtodModel
@dynamic addAutoMethod;
/**
  为addAutoMethod动态添加set和get方法
 **/
 +(BOOL)resolveInstanceMethod:(SEL)sel
{
    NSString *addSelectorStr = NSStringFromSelector(sel);
    //v@:@是一种符合 涉及到https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
    if ([addSelectorStr isEqualToString:@"setAddAutoMethod:"]) {
        class_addMethod(self, sel, (IMP)autoSetter, "v@:@");
    }else if ([addSelectorStr isEqualToString:@"addAutoMethod"]){
        class_addMethod(self, sel, (IMP)autoGet, "@@:");
    }
    return [super resolveInstanceMethod:sel];
}

void autoSetter(id self,SEL _cmd, id value){
    NSLog(@"set方法 === %@",value);
    
}

id autoGet(id self,SEL _cmd){
    return @"get方法";
}
 AutoMehtodModel *model = [[AutoMehtodModel alloc]init];
    model.addAutoMethod   = @"动态方法";
    NSLog(@"%@",model.addAutoMethod);

运行结果:

2018-03-27 10:53:07.875514+0800 OC_Categroy[962:61285] set方法 === 动态方法
2018-03-27 10:53:23.157687+0800 OC_Categroy[962:61285] get方法

参考文献:http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/

相关文章

  • 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 时...

  • 与Runtime相关的知识

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

  • 面试题二

    16. objc中向一个nil对象发送消息将会发生什么? 在 Objective-C 中向 nil 发送消息是完全...

  • react-native与原生Objective-C的通信

    Objective-C向react-native发送消息 当需要使用oc向rn发送消息时,只需要导入头文件RCTB...

网友评论

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

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