IOS runtime动态运行时二

在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);
2015-11-24 13:44:26.705 RunTime[6514:223611] 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);
2015-11-24 13:44:26.705 RunTime[6514:223611] Father Cui

3.method_invoke

Method method= class_getInstanceMethod([Son class], @selector(getNameWithfamily:));
    NSString *invokeName= method_invoke(son,method,@"Zhao");
    NSLog(@"%@",invokeName);
2015-11-24 13:44:26.705 RunTime[6514:223611] Son Zhao
    Method method= class_getInstanceMethod([father class], @selector(getNameWithfamily:));
    NSString *invokeName= method_invoke(father,method,@"Zhao");
    NSLog(@"%@",invokeName);
2015-11-24 13:51:28.288 RunTime[6546:231306] Father Zhao
时间: 2024-12-14 17:54:24

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

iOS 之动态运行时 runtime &lt;二&gt;

/* Working with Classes */ /** * Returns the name of a class. * * @param cls A class object. * * @return The name of the class, or the empty string if \e cls is \c Nil. */ OBJC_EXPORT const char *class_getName(Class cls) __OSX_AVAILABLE_STARTING(__MA

iOS 之动态运行时 runtime

前言: 最近研究runtime,觉得里面的东西好深,所以决定先把苹果提供的runtime.h文件简单的翻译一下,关于用法会在之后进行一些分享. /* Types */ #if !OBJC_TYPES_DEFINED /// An opaque type that represents a method in a class definition. typedef struct objc_method *Method; /// An opaque type that represents an i

iOS App 的运行时

App被启动时,从非运行状态到短暂的非激活状态,然后切换到运行状态或者后台运行状态.在启动过程中,操作系统对App创建了一个主线程来调用main方法. main方法是App的入口,用来调用UIKit框架和做一些程序运行前的预处理.XCode项目模板自动生成了mian方法,调用UIApplicationMain iOS也有自动内存管理,ARC(Automatic Refenerce Counting),@autoreleasepool中的代码的内存管理被ARC托管 App在后台运行时,会监听一些后

ios runtime 动态向类添加方法

1.定义C函数: void dynamicMethodIMP(id self, SEL _cmd) { NSLog(@"蜗牛也疯狂"); } 2.重写函数+(BOOL)resolveInstanceMethod:(SEL)sel +(BOOL)resolveInstanceMethod:(SEL)sel { class_addMethod([self class], sel, (IMP)dynamicMethodIMP, "[email protected]:");

C Runtime C运行时

顾名思义,C运行时是C程序运行时的环境,简称CRT C运行时主要包括以下几个部分: 1)引导程序(main)的入口函数和退出函数以及其依赖的各种函数 2)C的标准函数的实现 3)I/O功能的封装和实现 4)堆的封装和实现 5)C语言的特殊功能的实现 6)调试功能 7)其他 运行时(Runtime)是平台相关的,这里的平台指的是操作系统 它可以被理解成是C语言程序和不同操作系统平台的抽象层 * 并不是所有的C程序的操作都必须经由CRT实现 * CRT中并不都是C语言定义的操作

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

现在的ios开发中,我们通常会使用MVC模式.当我们拿到数据的时候,我们要把数据转成模型使用. 一般情况我们拿到的数据都是字典.这是我们就需要将字典转成模型对象了. 当对象的属性很少的时候,我们可以直接单独写出字典的键值,进行转换. _属性 = dict["键"] 当对象的属性很多的时候,我们可以利用KVC批量设置. setValuesForKeysWithDictionary:<#(NSDictionary *)#> 但是KVC批量转的时候,有个致命的缺点,就是当字典中的

iOS Runtime原理及使用

runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的代码.这就是 Objective-C Runtime 系统存在的意义,它是整个Objc运行框架的一块基石. RunTime简称运行时.OC就是运行时机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数.对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个

Objective-C Runtime的基本使用(iOS Runtime的初体验)

一.Runtime前言 最近研究Runtime,基础不够好,研究好久了,才了解一些些,知道个大概,这里做一个笔记.OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类的对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类,对象中的所有属性,方法,就算是私有方法以及私有属性都可以动态的修改.所以我所理解的就是 动态创建类,修改类,访问私有方法等一些基本特性,应该说理解runtime的基本用法吧! 二.Runtime简介 Runtime简称运行时,就是系统在运行的时候

iOS RunTime你知道了总得用一下

说点题外话: 我刚来现在这家公司的时候,老板让我下载一个脉脉,上去找找自己的同行,多认识些同行.其实初衷的好的,但最近这两天我把它卸载了,不为别的,负能量太多!iOS这行自从2016就没景气过,在这行混,这些自己也肯定都知道.但就是受不鸟铺天盖地的多久没找到工作,满大街都是iOS程序猿这些话题.看了也给我带不来任何的作用,你唯一能做的就是安安静静的做好自己该做的.自己入iOS这行也一年半过了,除去培训的那个几个月,真正摸爬滚打也一年多了,有时候想想,其实也没觉得有多差,以后怎样不知道,但至少现在