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

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

相关文章
|
2月前
|
开发框架 Dart 开发工具
使用Flutter开发一套可同时运行在Android和iOS平台的代码
Flutter是一种跨平台移动应用开发框架,它允许开发者使用单一代码库构建高性能、美观且可在多个平台上运行的应用程序。本文将介绍如何使用Flutter开发一套同时适用于Android和iOS平台的代码。
|
4月前
|
开发工具 iOS开发
iOS 项目无法在模拟器运行解决办法
iOS 项目无法在模拟器运行解决办法
252 0
|
5月前
|
iOS开发 芯片 MacOS
macOS Big Sur 正式发布并已开放下载,支持原生运行 iOS 和 iPadOS App
macOS Big Sur 正式发布并已开放下载,支持原生运行 iOS 和 iPadOS App
71 0
|
移动开发 iOS开发 Perl
ReactNative运行IOS在Xcode 11.0编译报错
ReactNative运行IOS在Xcode 11.0编译报错
83 0
ReactNative运行IOS在Xcode 11.0编译报错
|
编解码 安全 Linux
flutter 在windows和linux上运行IOS UI模拟器
之前发视频总是有人留言,我用的什么模拟器,今天给大家说一下 我一般用的是device_preview这个插件,这个插件的闲置是只能做UI上的模拟,并没有真正的运行环境。 近似您的应用程序在另一台设备上的外观和性能。
277 0
|
移动开发 开发框架 JavaScript
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(四)
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解
398 0
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(四)
|
JSON JavaScript 前端开发
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(三)
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解
415 0
|
JavaScript 前端开发 Java
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(二)
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解
233 0
|
Web App开发 JavaScript 前端开发
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(一)
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解
858 0
让你的iOS应用程序支持运行JavaScript脚本:JavaScriptCore框架详解(一)
|
安全 开发工具 iOS开发
iOS运行时函数替换框架——RSSwizzle
iOS运行时函数替换框架——RSSwizzle
281 0
相关产品
云迁移中心
推荐文章
更多