在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. C# winform无边框窗体移动

    public partial class MessageHints : Form { //窗体移动API [DllImport("user32.dll")] public stat ...

  2. eFrameWork学习笔记-eList

    HTML: <div style="margin:8px;"> <h1>.不分页</h1> <asp:Repeater id=" ...

  3. 如何创建一个自己的.NET Core Global Tools

    索引 NET Core应用框架之BitAdminCore框架应用篇系列 框架演示:https://www.bitadmincore.com 框架源码:https://github.com/chenyi ...

  4. c# 图片等比缩略

    public Bitmap getnew(Image bit, int TargetWidth, int TargetHeight)//beishu参数为放大的倍数.放大缩小都可以,0.8即为缩小至原 ...

  5. IIS服务器添加网站

    1.添加IIS服务:对“我的电脑”右键,管理,点击服务和应用程序,如果下面没有”Internet Information Services(IIS)管理器“,打开控制面板,点击程序,启用或者关闭Win ...

  6. 自注意力机制(Self-attention Mechanism)——自然语言处理(NLP)

    近年来,注意力(Attention)机制被广泛应用到基于深度学习的自然语言处理(NLP)各个任务中.随着注意力机制的深入研究,各式各样的attention被研究者们提出.在2017年6月google机 ...

  7. 列表和range、元组

    1.listt.append()默认追加在后面 2.list.insert(索引,“元素”)按索引添加 3.list.extend()可添加多个字或字母的字符串,也可以是列表 4.list.pop() ...

  8. 【OCP认证12c题库】CUUG 071题库考试原题及答案(25)

    25. choose the best answer Evaluate the following SQL statement: ALTER TABLE hr.emp SET UNUSED (mgr_ ...

  9. 如何获取token值

    登录的时候需要拿到token值,需要跟后端配合才能拿到 官方说明: https://developers.weixin.qq.com/miniprogram/dev/api/api-login.htm ...

  10. Jmeter分布式测试实战

    一.Jmeter分布式测试基础 1.Jmeter分布式测试原因: 在使用Jmeter进行接口的性能测试时,由于Jmeter 是JAVA应用,对负载机的CPU和内存消耗比较大.所以当需要模拟数以万计的并 ...