在C#、Java中有编译时多态和运行时多态,在OC中,只有运行时的多态,这与它的运行机制有关。OC中,方法的调用是通过消息的传递来进行的。在IOS runtime动态运行时一http://www.cnblogs.com/5ishare/p/4708647.html中主要大致介绍了下运行时的过程,这篇主要看下消息转发(实现多态的基础)。

一.引入

在<objc/objc-runtime.h>中有两个.h,<objc/runtime.h>和<objc/message.h>,这篇主要了解<objc/message.h>

二.消息转发

在该类中主要有3中方法 (其他几种我也不知道所以有3种):objc_msgSend、objc_msgSendSuper、method_invoke。

像objc_msgSend_stret、objc_msgSend_fpret函数返回结构体、浮点数这些需要经过CPU特殊处理,所以不用太留意。它们就是上面3种的变体,当返回的是结构体、浮点数时,会调用 _stret、_fpret这些。

三.方法的使用

在使用之前有几个注意点:

1.要引入框架<objc/objc-runtime.h>

2.直接写入运行时代码会报错需要按下图设置一下

1).objc_msgSend

在IOS runtime动态运行时一博客中也写了oc中方法调用其实是转为objc_msgSend来实现消息转发。

2).objc_msgSendSuper

这个是将消息转发给父类。方法的第一个参数是一个objc_super类型的结构体。结构体主要包括两个变量:

1.receiver:即消息的实际接收者

2.superClass:指针当前类的父类

struct objc_super {
        /// Specifies an instance of a class.
       __unsafe_unretained  id receiver;
        /// Specifies the particular superclass of the instance to message.
       __unsafe_unretained Class super_class;

    };
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)

3).method_invoke

在C#多线程中有invoke,这里和C#类似,用于方法的调用。这里需要传结构体Method。可以通过runtime.h来获得类中的某个Method

method_invoke(id receiver, Method m, ...) 

四、测试结果

在项目中创建了一个Father类和一个继承Father的Son。Son类重写了父类的-(NSString *)getNameWithfamily:(NSString *)family方法。

#import <Foundation/Foundation.h>

@interface Father : NSObject
-(NSString *)getNameWithfamily:(NSString *)family;
@end
//
//  Father.m
//  RunTime
//
//  Created by City--Online on 15/11/24.
//  Copyright © 2015年 City--Online. All rights reserved.
//

#import "Father.h"

@implementation Father
-(NSString *)getNameWithfamily:(NSString *)family;
{
    return [NSString stringWithFormat:@"Father %@",family];
}
@end
//
//  Son.h
//  RunTime
//
//  Created by City--Online on 15/11/24.
//  Copyright © 2015年 City--Online. All rights reserved.
//

#import "Father.h"

@interface Son : Father

@end
//
//  Son.m
//  RunTime
//
//  Created by City--Online on 15/11/24.
//  Copyright © 2015年 City--Online. All rights reserved.
//

#import "Son.h"

@implementation Son
-(NSString*)getNameWithfamily:(NSString *)family
{

    return [NSString stringWithFormat:@"Son %@",family];
}
@end

1.objc_msgSend 通过objc_msgSend调用son的getNameWithfamily:方法 返回为字符串、一个参数

    Son *son=[[Son alloc]init];
    NSString *name= objc_msgSend(son, @selector(getNameWithfamily:),@"Tom");
    NSLog(@"%@",name);
-- :::] Son Tom

2.objc_msgSendSuper 通过objc_msgSendSuper调用父类的方法类似[super xxxxx],主要是第一个objc_super类型的结构体.

struct objc_super objcsuper;
    objcsuper.receiver=father;
    objcsuper.super_class=[son superclass];

    NSString *superName=objc_msgSendSuper(&objcsuper, @selector(getNameWithfamily:),@"Cui");
    NSLog(@"%@",superName);
-- :::] Father Cui

3.method_invoke

Method method= class_getInstanceMethod([Son class], @selector(getNameWithfamily:));
    NSString *invokeName= method_invoke(son,method,@"Zhao");
    NSLog(@"%@",invokeName);
-- :::] Son Zhao
    Method method= class_getInstanceMethod([father class], @selector(getNameWithfamily:));
    NSString *invokeName= method_invoke(father,method,@"Zhao");
    NSLog(@"%@",invokeName);
-- :::] Father Zhao

上面主要介绍了下<objc/message.h>一些基础,运行时还包括<objc/runtime.h>,这个类的作用和C#、Java的反射有些类似。也是获取类名、属性、方法等。之前的属性关联就是利用该类中的方法。在网上也找了下一些博客,发现http://blog.csdn.net/a19860903/article/details/45044701中写的蛮详细的,可以参考来看。

IOS runtime动态运行时二的更多相关文章

  1. IOS runtime动态运行时一

    对运行时不太了解,今天小伙伴橄榄油陈高给发了个链接 ,看了一部分先存着以后慢慢品 http://www.cocoachina.com/ios/20141018/9960.html http://blo ...

  2. ios开发- 利用运行时(runtime)字典转模型

    现在的ios开发中,我们通常会使用MVC模式.当我们拿到数据的时候,我们要把数据转成模型使用. 一般情况我们拿到的数据都是字典.这是我们就需要将字典转成模型对象了. 当对象的属性很少的时候,我们可以直 ...

  3. iOS Runtime原理及使用

    runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...

  4. iOS RunTime你知道了总得用一下

    说点题外话: 我刚来现在这家公司的时候,老板让我下载一个脉脉,上去找找自己的同行,多认识些同行.其实初衷的好的,但最近这两天我把它卸载了,不为别的,负能量太多!iOS这行自从2016就没景气过,在这行 ...

  5. iOS runtime的理解和应用

    项目中经常会有一些的功能模块用到runtime,最近也在学习它.对于要不要阅读runtime的源码,我觉得仅仅是处理正常的开发,那真的没有必要,只要把常用的一些函数看下和原理理解下就可以了. 但是如果 ...

  6. 乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时

    Dapr是一个由微软主导的云原生开源项目,国内云计算巨头阿里云也积极参与其中,2019年10月首次发布,到今年2月正式发布V1.0版本.在不到一年半的时间内,github star数达到了1.2万,超 ...

  7. 【原】iOS动态性(二):运行时runtime初探(强制获取并修改私有变量,强制增加及修改私有方法等)

    OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类.对象中的所有属性.方法,就算是私有方法以及私有属性都是可以动 ...

  8. iOS开发——高级技术OC篇&运行时(Runtime)机制

    运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档 ...

  9. 【原】iOS动态性(五)一种可复用且解耦的用户统计实现(运行时Runtime)

    声明:本文是本人 编程小翁 原创,转载请注明. 为了达到更好的阅读效果,强烈建议跳转到这里查看文章. iOS动态性是我的关于iOS运行时的系列文章,由浅入深,从理论到实践.本文是第5篇.有兴趣可以看看 ...

随机推荐

  1. 后台生产验证码code和byte[]图片

    引用命名空间 using System.Drawing;using System.Drawing.Drawing2D;using System.Drawing.Imaging;using System ...

  2. c#设计模式之观察者模式(Observer Pattern)

    场景出发 一个月高风黑的晚上,突然传来了尖锐的猫叫,宁静被彻底打破,狗开始吠了,大人醒了,婴儿哭了,小偷跑了 这个过程,如果用面向对象语言来描述,简单莫过于下: public class Cat { ...

  3. WPF 分享一种设置程序保存配置文件的方法

    最近需要做一个配置程序,主要给其他程序做相关配置的小工具. 配置项蛮多的,一般我们都是将各个配置项写到配置文件的节点中,比如App.config文件或者自定义的xml文件. 因为我用的是wpf,MVV ...

  4. GO语言官方中文教程!

    官方中文教程网址:https://tour.go-zh.org/basics/1 推荐理由:简洁,一句废话没有,对于初学者可以让大家快速掌握GO语言! 注意问题:如果不能访问,你懂的! 教程截图:

  5. java—过虑器基础(47)

    在web项目中就只有三大组件: Filter过虑器 监听器. Servlet 在web中过虑器就是一个类javax.servlet.Filter. 过虑器是用于在执行时,过虑用户的请求(request ...

  6. php扩展memcache和memcached区别?以及memcached软件的介绍

    引用“http://www.vicenteforever.com/2012/03/memcache-different-memcached/” memcached是一个软件,而PHP包括了memcac ...

  7. IT男装逼利器:如何像黑客一样聊天 Mojo-Webqq

    电影里的黑客们聊天不想我们生活中的一样,用QQ.微信的客户端,都是通过命令行来进行聊天交流的,大概是为了提升逼格吧.(文末有福利~) 本文作者:KevinSVIP 今天发现一个有趣的项目:使用mojo ...

  8. NEST - How can i do multiple nested aggregation?

    question: How can I do multiple nested aggregation? I have tried something like this: Aggregations(x ...

  9. 总结day11 ----函数的学习(2)

    内容大纲 一: 函数的运行 二: 闭包 三: 迭代器 四: 生成器 五: 列表生成器 六: 列表推导式 七: 生成器表达式 八: 匿名函数 一: 函数的运行 1:函数名是一个特殊变量 def func ...

  10. C#-WebForm-LinQ(一)-LinQ:语言集成查询(Language Integrated Query)-增删改查、属性扩展

    LinQ-语言集成查询(Language Integrated Query) 高集成化的数据库访问技术 LINQ 2 SQL 实际是将数据库的表映射成程序中的类 会把数据库的表名原封不动的变成类名 数 ...