iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制

你要知道的runtime都在这里

转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289

本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向:

本文是系列文章的第二篇文章从runtime开始: 深入理解OC消息转发机制,主要从runtime出发讲解OC的消息传递和消息转发机制。

你不知道的msg_send

我们知道在OC中的实例对象调用一个方法称作消息传递,比如有如下代码:

NSMutableString *str = [[NSMutableString alloc] initWithString: @"Jiaming Chen"];
[str appendString:@" is a good guy."];

上述代码中的第二句str称为消息的接受者,appendString:称作选择子也就是我们常用的selectorselector参数共同构成了消息,所以第二句话可以理解为将消息:"增加一个字符串: is a good guy"发送给消息的接受者str
OC中里的消息传递采用动态绑定机制来决定具体调用哪个方法,OC的实例方法在转写为C语言后实际就是一个函数,但是OC并不是在编译期决定调用哪个函数,而是在运行期决定,因为编译期根本不能确定最终会调用哪个函数,这是由于运行期可以修改方法的实现,在后文会有讲解。举个栗子,有如下代码:

id num = @123;
//输出123
NSLog(@"%@", num);
//程序崩溃,报错[__NSCFNumber appendString:]: unrecognized selector sent to instance 0x7b27
[num appendString:@"Hello World"];

上述代码在编译期没有任何问题,因为id类型可以指向任何类型的实例对象,NSString有一个方法appendString:,在编译期不确定这个num到底具体指代什么类型的实例对象,并且在运行期还可以给NSNumber类型添加新的方法,因此编译期发现有appendString:的函数声明就不会报错,但在运行时找不到在NSNumber类中找不到appendString:方法,就会报错。这也就是消息传递的强大之处和弊端,编译期无法检查到未定义的方法,运行期可以添加新的方法。

讲了这么多OC究竟是怎么将实例方法转换为C语言的函数,又是如何调用这些函数的呢?这些都依靠强大的runtime

在深入代码之前介绍一个clang编译器的命令:

clang -rewrite-objc main.m
该命令可以将.m的OC文件转写为.cpp文件

有如下代码:

@interface Person : NSObject

@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) NSUInteger age;

- (void)showMyself;

@end

@implementation Person

@synthesize name = _name;
@synthesize age = _age;

- (void)showMyself {
    NSLog(@"My name is %@ I am %ld years old.", self.name, self.age);
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
         //为了方便查看转写后的C语言代码,将alloc和init分两步完成
        Person *p = [Person alloc];
        p = [p init];
        p.name = @"Jiaming Chen";
        [p showMyself];
    }
    return 0;
}

通过上述clang命令可以转写代码,然后找到如下定义:

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值