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中写的蛮详细的,可以参考来看。

相关文章
|
10天前
|
安全 数据安全/隐私保护 iOS开发
基于iOS的动态权限管理实现
【4月更文挑战第9天】 随着移动互联网的快速发展,用户对应用程序的隐私安全要求越来越高。在iOS平台中,如何实现动态权限管理成为了开发者关注的焦点。本文将详细介绍一种基于iOS的动态权限管理实现方法,通过使用Core Motion框架和Notification Center,实现对用户位置信息的实时监控和动态权限申请。
|
6月前
|
API iOS开发
iOS面试关于runtime
iOS面试关于runtime
55 0
|
3月前
|
iOS开发
iOS实时查看App运行日志
iOS实时查看App运行日志
31 0
|
3月前
|
存储 监控 iOS开发
查看ios app运行日志
查看ios app运行日志
23 0
|
3月前
|
iOS开发
iOS实时查看App运行日志
在移动应用开发过程中,经常需要查看应用在运行时输出的日志信息。而在iOS上,我们可以通过克魔助手提供的功能来实现方便快捷地查看设备上的日志。本文将介绍如何使用克魔助手来实时查看iOS设备上的应用日志。
iOS实时查看App运行日志
|
9月前
|
Android开发 iOS开发 Windows
无影产品动态|iOS & Android客户端6.0.0版本发布,提升触控灵敏度,操作体验更丝滑
无影ios & Android客户端6.0.0版本发布!移动端触控体验更舒适,用户操作更便捷,一起来看看!
676 0
无影产品动态|iOS & Android客户端6.0.0版本发布,提升触控灵敏度,操作体验更丝滑
|
9月前
|
存储 缓存 iOS开发
iOS 轻量化动态图像下载缓存框架实现
日常开发过程中,图片的下载会占用大量的带宽,图片的加载会消耗大量的性能和内存,正确的使用图片显得尤为重要。 同样也经常需要在各类型控件上读取网络图片和处理本地图片,例如:UIImageView、UIBtton、NSImageView、NSButton等等。
iOS 轻量化动态图像下载缓存框架实现
|
9月前
|
C语言 C++ iOS开发
iOS中C++静态全局变量的动态初始化时序
一个由于C++初始化失败导致Realm初始化失败的Crash
131 1
|
9月前
|
开发框架 Dart 开发工具
使用Flutter开发一套可同时运行在Android和iOS平台的代码
Flutter是一种跨平台移动应用开发框架,它允许开发者使用单一代码库构建高性能、美观且可在多个平台上运行的应用程序。本文将介绍如何使用Flutter开发一套同时适用于Android和iOS平台的代码。
|
10月前
|
Shell
(Mac)remotedebug-ios-webkit-adapter 无法运行,出现以下错误:ios_webkit_debug_proxy找不到。请安装 ios_webkit_debug_proxy (https://github.com/google/ios-webkit-debug-proxy) #74
(Mac)remotedebug-ios-webkit-adapter 无法运行,出现以下错误:ios_webkit_debug_proxy找不到。请安装 ios_webkit_debug_proxy (https://github.com/google/ios-webkit-debug-proxy) #74
357 0