Runtime合集

iOS – isa、superclass指针,元类superclass指向基类自身

1. 什么是Runtime

Runtime是一个库,坐落usr/include/objc, 经常用的api坐落该库下的runtime.h文件中,在运用时需求引证头文件#import <objc/runtime.h>

2. Runtime 做什么用

经过Ru音讯机制面试题ntime,咱们能够在App作业期动态的创立政策、objective case检查政策、修改类、政策的办法,能够说Runtime苹果是Objec苹果xtive-C的作业机遇制的根底

3. 音讯机制的基本原理

声明一个Person类, 类包括两个政策办法(此处为了编译后查找代码便利,我把函数名命为personSlios下载eep,此处不符合代码命名标准请忽略)

@implementation Person
- (void)eatFood:(NSString *)foodName {
NSLog(@"person eat food : %@", foodName);
}
- (void)personSleep {
NSLog(@"person is sleeping...");
}
@end

咱们在外界调用eatFood,编译成cpp检查

    Person *person = [[音讯机制怎样调用Person alloc] init];
[person eatFood:@"baozi"];
[person personSleep];

cpp

    Person *person = ((Person *(*)(id, SEL苹果x))(void *)objc_msgSend)((id)((数据结构教程第5版李春葆答案Person *(数据结构c言语版*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
((void (*)(id, SEL, NSString * _Nonnull))(vo苹果xid *)objc_msgSend)((id)person, sel数据结构c言语版第二版课后答案_registerName("eatFood:"), (NSString *)&__NSConstantStringImpl__var_folders_44_1ht3l6g55dv59_5s62wsv苹果手机_bm0000gn_T_ViewController_88ee85_mi_0);
((void (*)(id, SEL))(void *)objc_msgSend)数据结构严蔚敏((id)person, sel_registerName("personSleep"));音讯机制怎样调用

把代码简化一下,咱们可知编译后的[person eatFood]变成了

objc_msgSend(reciv数据结构c言语版er, Selector)

objc_音讯机制原理msgSend(reciver, Selector, org1, org2, …)

作业期阶段:音讯接收者reciver寻觅Selector去实施

  1. 经过reciverisa指针找到revicerCios8备忘录lass
  2. Classcache(方苹果电影法缓存)的散列表寻觅对应的IMP(办法结束)
  3. 假定2.没找到,就持续在Classmethod list(办法列表)中找对应的selector,假定找到了,填充到Class的cache中并回来selector
  4. 假定3.没找到,就持续在其父苹果电影类中找
  5. 一旦找到对应的selector,直接实施reciverselectorIMP(办法结束)
  6. 若找不到对应的selector,需求音讯被转发或暂时向这个reciver增加selector,不然会发生溃散

4.Runtime中的概念

4.1 objc_msgSe数据结构c言语版第二版课后答案nd

全部的Obobjective c言语jective-Cobjective complement办法编译后都会变成对objc_msgSend的调苹果8用,

4.2 Class

struct objc_class {
Class _Nonnull isa;                                         //objc_class结构体的实例指针ios体系
#数据结构试验一线性表试验报告if !__OBJC2__
Class _ios体系Nullable super_class;                                //指向父类的指针
const char * _Nonn数据结构与算法ull name;                                 //类的称号
long version;                                               //类的版别信息,默以为0
long info;                                                  //类的信息,供作业期运用的一些位标识
long instance_size;                                         //该类的实例变量巨细
struct数据结构 oobjective c言语bjc_ivar_list * _Nullable ivars;                    //该类的实例变量列表
struct objc_methios模拟器od_list * _Null苹果在印遭严峻冲击able * _Nullable m音讯机制怎样调用ethodLists;//办法界说的列表
struct objc_cache * _Nonnull caobjective complementche;                         //办法缓存;音讯机制java
struct objc_protocol_list * _Nullable proto音讯机制结构cols;            //恪ios最好玩的手游守的协议列数据结构表;
#end数据结构题库及答案if
}

从中能够看出,objc_classobjective clauses是什么意思构体 界说了许多变量:数据结构自身的全部实例变量(ivars)、全部办法界说(methodLists)、恪守的协议列表(protocols)等。objc_class 结构体 存放的数据称为 元数据(metadata)

objc_class结构体的第一个成员变量是isa指针,isa指针保存的是所属类的结构体的实例的指针,这儿保存的便是objc_class结构体的实例指针,换个名字便是政策,也便是说,Class的本质便是一个方objective correlative针,咱们称为 类政策

4.3 Object苹果

在objc.h中, Object被界说成了objc_class结构体

/// Represents an instance of a cl数据结构知识点总结ass.
typ数据结构严蔚敏edef struct objc_class *Class;
/// Represents an instance of a class.
struct objc_object {
Classobjective clause什么意思 _Nonnull isa;       //objc_object 结构体的实例指针
};
/// A pointerios退款 to an instance of aobjective clause什么意思 class.
typedef struct objc_object *id;

从中能够看出,objc_object结构体只包括了一个Class类型的isa指针,也就音讯机制是同步机制吗是说一个Object(政策)仅有保存的便是它所属Class(类)的地址,当咱们对一个政策进行办法调用时,苹果13比如[receiios14.4.1更新了什么ver selector], 它会经过objc音讯机制是同步机制吗_object结构体的i音讯机制mqsa指针去ios14桌面布局图片找到对应的object_class结构体,然后在数据结构题库及答案object_class结构体的methodL数据结构严蔚敏ists中找到咱们数据结构c言语版调用的方苹果7法,然后实施

4.4 Meta Class

从上边咱们能看出,政策的(objc_object结构体)的isa指针指向对应类政策(object_class结构体),那么类政策(object_class结构体)的isa指针又指向什么呢
object苹果11_class结构体的isa指针实际上指向ios14的是类政策自身的meta-class(元类)

元类便是一个类政策所属的类。一个政策所属的类叫做类政策,一个类政策所属的类便是元类

Runtime中把类数据结构c言语版第二版课后答案政策所属ios最好玩的手游类型叫做metaobjective clauses-class(元类),用于描绘类政策自身所具有的特征,而在元类的methoobjective clauses是什么意思中文dLists中,保存了类的办法列表,即所谓的类办法,并且类政策中的isa指针指向的便是元类,每个类ios是什么意思政策有且仅有一个与之相关的元类

3. 音讯机制的基本原理中讲到,政策的调用进程,是经过方数据结构题库及答案针的isa指针找到类政策,在类政策的methodLists中找到对应的selector

而类办法的调用进程与政策的调用差不多,流程如下:

  1. 经过类政策is数据结构c言语版第二版课后答案a指针找到所属的meta音讯机制原理-class(元类)
  2. meta-classmethodLists中找到对应的selector
  3. 实施对应的selector

下面看一个示例:

NSString *str =objective clause什么意思 [NSString stringobjective c语法WithFormat:@"%d,%s", 3. @"test"];

上边的示例中,stringWiios下载thFormat被发送给了NSString类,音讯机制NSStringios8备忘录经过isa指针找到NSStrin苹果12g的元类,然后在该元类的办法列表中找到对应的stringW音讯机制是同步机制吗ithFormat:办法,然后实施ios是什么意思该办法

4.5 实例政策、类、元类的联络ios14桌面布局图片

iOS – isa、superclass指针,元类superclass指向基类自身

iOS - Runtime根底

4.6 Meios14.4.1更新了什么th音讯机制od

object_objective correlativeclass结构体中的methodLists(办法列表)中存放数据结构难学吗的元素便是Method苹果12(办法)

objc/runtime.h音讯机制是同步机制吗,标明Met数据结构难学吗hod的‘objc_method结构体’数据结构如下

struct objc_method {
SEL _Nonnull method_name;       //办法名
charios体系 * _Nullable method_types;  //办法类型
IMP _Nonnul数据结构与算法l method_imp;        //办法结束数据结构严蔚敏
}
  1. SEL method_name 办法名

SEL的界说在objc/objc.h

/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;

SEL是一个指向objc_selector的指针,可是在runtime相关头文件中并没有找数据结构c言语版到明晰的界说。不过,经过检验咱们能够得出:S音讯机制和事情机制EL只是一个保存办法名的字符串

    SEL sel = @selector(viewDidLoad);
NSLog(@"%s", sel);
SEL sel1 = @selector(test音讯机制);
N数据结构题库及答案SLog(@"%s", sel1);

输出为:

2021-05-10 21:58:24.705590+0800 RuntimeDemo[2266:67998] viewDidLoad
2021-ios下载05-10 21objective clauses是什么意思中文:58:24.705746+0800 RuntimeDemo[2266:67998] test
  1. IMP _Nonnull数据结构c言语版 method_imp 办法结束

IMP的界说相同在ob数据结构严蔚敏jc/objc.h

/// A pointer to the function of a method imple数据结构c言语版mentation.
#if !OBobjective caseJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP苹果官网)(void /* id, SEL, ... */ );
#else
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...);
#endif

IMP的本质是一个函数指针数据结构与算法,所指向的便是办法的结束,IMP用来找到函数的地址,然后实施函数
3. char * _Nullable method_ty音讯机制原理pes; 方苹果13法类型
办法类型method_types是个字符串,用音讯机制面试题来存储办法的苹果参数类型和回来值类型

到这儿,Method的结构就已经很清楚了,MethodSEL(办法名)IMP(函数指针ios最好玩的手游)相关起来,当对一个政策发送消ios退款息时,会经过给出的SEL(办法名objective complement)去找到IMP(函数指针)音讯机制怎样调用,然后实施

5.数据结构c言语版第二版课后答案 Runtime音讯转发objective c言语

数据结构知识点总结3. 音讯机制的基本原理毕竟一步咱们提到:若找不到对应的selector,音讯被转发或许暂时向receiver增加这个selector对应的苹果12结束办法,不然就会溃散

当一个办法找不到的时分,Runtime供给了音讯动态解析、音讯接受者重定向、ios退款音讯定向objective c言语等三步处理消Objective-C息,具体流程如下

iOS - Runtime根底

5.1 音讯动态解析(动态增加办法)

Objios14桌面布局图片ective-C作业时会调用+resolveClassMethod+re数据结构试验一线性表试验报告solveInstanceMethod,让你有机遇ios8备忘录供给一个函数结束。前者在政策办法未找到时调用,后者在类办法未找到时调用。咱们能够经过重写这两个办法,增加其他函数结束,并回来YES,那作业时体系就会重新启动一次音讯发送的进程

首要用到的办法如下
动态解析的办法坐落

// 坐落objc/NSObject.h
+ (BOOL)苹果在印遭严峻冲击resolveios8备忘录ClassMethod:(SEL)sel ;
+ (BOOL)resolveInstanc苹果13eMethod:(SEL)sel;
//坐落 objc/runtime.h
/**
* 向一个类增加新办法,此办法需求给定称objective c根底教程号及参数
*
* @param cl数据结构知识点总结s 要被增加办法的类
* @param name selector办法称ios模拟器号
* @param imp 结束办法的音讯机制mq函数指针
* @param ty苹果官网pes 只想函数的回来值与参数类型
*
* @return 假定增加办法成功回来YES,不然回来NO
*/
OBJC_EXPORT BOOL数据结构试验一线性表试验报告
class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp,ios模拟器
const char * _Nullable types) ;

代码示例:

//
//  View数据结构教程第5版李春葆答案Controlleios14桌面布局图片r.m
//  RuntimeDemo
//
//  Created by Terence on 2021/5/10.
//  Copyright  2021年 Ter音讯机制mqence. All right数据结构严蔚敏第二版课后答案s reserved.
//
#import "ViewControobjective complementller.h"
#import "objc/runtimeobjective c语法.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)ios14.4.1更新了什么viewDidLoad {
[super viewDidLoad];
[self performSelector:@selector(eat)];
}
+ (BOOL)resolve音讯机制结构InstanceMethod:(SEL)sel {
if (sel == @selector(eat)) {
class_addMethod(self.class, sel, (IMP)eatMethod, "v@:");
return YES;
}
return [super res音讯机制怎样调用olveInstanceMethod:sel];
}
void eatMeth数据结构c言语版od(id obj, SEL _cmd) {
NSLog(@"eat food");
}
@end

输出效果:

2021-05-10 23:10:23.110858+0800 RuntimeDemo[3451:122697] eat food

从上边的比如中,咱们能够看出,虽然咱们没有结束fun办法,可是经过重写resolveInstance音讯机制是同步机制吗Method音讯机制和事情机制办法,运用class_addMethod 办法动态的增加了政策办法eatMethod,并实施,成功调音讯机制结构用了eatMethod办法

class_addMethod办法中的特别参数v@:,可参看苹果官方文档中关于Type Encodings的说明:Type Encodings

5.2 音讯动态转发

假定上一步中+resoobjective c根底教程lveClassMethod+resolveInstanceMethod没有增加其它函数结束,作业时就会进行到下一步:音讯接收者重定向

假定当时苹果13政策结束了- forwardingTargetForSelector:+forwar音讯机制mqdingTargetForSelector:办法,objective c言语Runtime就会调用这个办法,容许咱们将音讯的接收者转发给其它政策

/苹果/ 重定向类办法的音讯接收者,回来一个类或实例政策
+ (id)forwardingTargetForSelector:(SEL)aSelector;
// 重定向办法的音讯接收者,回来一个类ios最好玩的手游或实例政策
- (id)forwardingTargetForSelector:(SEL)aSeobjective clauses是什么意思中文lector;苹果在印遭严峻冲击

留神:

  1. 类办法和政策办法音讯转发第二步调用的办法不一样,前者是+forwardingTarios8备忘录getForSelectobjective c语法or办法,后者是-forwardingTargetForSelector办法
  2. 这儿-resolveClassMethod:或许-resolveIios14桌面布局图片nstanceMethod无论是回来YES仍是NO,只需其间没有增加其它函数结束,作业时都会进行下一步

代码示例:

@implementation Person
- (void)eatFood:(NSString *)foodName {
NSLog(@"person eat fooios最好玩的手游d : %@", foodName);
}
- (void)personSleep {
NSLog(@"person is sleeping...");
}
@end
@implementation音讯机制是同步机制吗 ViewControios14.4.1更新了什么ller
- (void)viewDidLoa苹果d {
[super vie数据结构c言语版wDidLoad];
[self performSelector:@数据结构严蔚敏第二版课后答案selector(personSleep)];
}
+ (BOOL)resolveClassMethod:(iOSSEL)sel {
return YES;
}
+ (BOOL)resolv音讯机制eInstanceMethoiOSd:(SEL)sel {
return YES;
}
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (aSelector == @selec音讯机制面试题tor(personSleep数据结构与算法)) {
return [[Person alloc] init];
}
return [super forwardingTargeios14桌面布局图片tForSelector:aSele音讯机制怎样调用ctor];
}
@end

打印输出:

2021-05-11 11:50:55.352147+数据结构c言语版0800 LoadInitializeDObjective-Cemo[47468:ios退款1985216] person is sleeping...

能够看到,虽然当时ViewController没有结束fun办法,+resolveInstanceMethod:也没有增加其它函数结束,可是咱们经过forwardin数据结构c言语版gTargetForSelector把当时ViewController的办法转发给了per音讯机制和事情机制son政策去实施了

咱们经过forwardingTargetForSelector能够修改音讯的接收者,该方苹果在印遭严峻冲击法回来参数是一个政策,假定这个政策不是nil,也不是self,体系会将作业的音讯转发给数据结构与算法这个政策实施。不然,持续进行下一步:音讯重定向流程

5.ios14.4.1更新了什么3 音讯重定向

假定经过音讯动态解析、音讯接收者重定向,Runtime体系仍是找不到相应的办法结束而无法照顾音讯,Runtim苹果在印遭严峻冲击e系数据结构c言语版第二版课后答案统会运用-methodSignatureForSelector:+methodSignatureForSele数据结构题库及答案ctor:办法获取函数的参数和回来值类型

  • 假定methodSignatureForSelector回来了一个NSMethodSignature政策objective c根底教程(函数签名),Runtime体系就会创立ios体系一个NSInvocation政策数据结构c言语版。并经过forwardInvocation:音讯告诉当时政策,给予此次音讯发送毕竟顺次寻觅IMP的机遇
  • 音讯机制怎样调用methodSignatureForSelecotr:回来nil,则Runtime体系会宣告doesNotRecognizeSelios是什么意思ector:音讯,程序也就溃散了

所以咱们能够在forwardingInvocation:办法中对音讯进行转发

留神:类办法和政策办法音讯转发第三步调用的办法相同不一样
类办法调用的是:

  1. +me数据结构严蔚敏thodSignatureForSelector
  2. + forwardInvocation:
  3. doesNotRecognizeSelector:

政策办法调用的是
-苹果在印遭严峻冲击method苹果手机SignatureForSelector:
-forwardingInvocation:
doesNotRecognizeSelector:

用到的办法

//获取类办法函数的参数和回来值类型,回来签名
+ (NSMios最好玩的手游ethodSignature *)methodSignatureForSelector:(SEL)aSelector;
// 类办法音讯重定向
+ (void)forwardInvocation:(NSInvocation *)anInvocation {
NSLog(@"aInvocation: %@", anInvocation);
/数据结构教程第5版李春葆答案/ 获取政策办法函数的参数和回来值类型,回来签名
- (NSMethodSignature *音讯机制)methodSignatureForSelector:(SEL)aSelector;
// 政策办法音讯重定向
- (void音讯机制java)forwardiOSInvocatiios是什么意思on:(NSInvocation *)anInvocation {
NSLog(@"aInvocation: %@", anInvoca苹果7tion);
}
}

代码示例

#import "苹果电影ViewController.h"
#import "Person.h"
#import <objc/runtime.h>
@iobjective complementnterface ViewController ()
@end
@implementation V数据结构题库及答案iewController
- (void)viewDidLoad {
[super viewDidLoad];
[ViewController performSelector:@selector(personWakeup)];
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
//为音讯机制是同步机制吗了进行下一步,音讯接收者重定向
return YES;
}
//音讯接收者重定向
+ (id)forwardingTargetForSelector:ios14.4.1更新了什么(SEL)aSelector {
//为了进行下一步,音讯重定向
return [super forwardingTargetForSelector:aSelector];
}
// 获取函数的参数和回来值类型objective clauses,回来签名
+ (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
if ([NSStringFromSelector(aSelector) isEqualToStrinobjective clauses是什么意思g:@"personWakeup"]) {
return [NSMethod音讯机制结构Signature signatureWithObjCT数据结构与算法ypes:"v@:"];
}
return [super苹果12 methodSigobjective complementnatureForSel数据结构难学吗ector:aSelector];
}
// 音讯重定向
+objective clauses是什么意思 (void)forwardInvocation:(NSInvocation *)anInvocation {
NSLog(@"aInvocation: %@", anInvocation);
SEL sel =objective clauses是什么意思中文 anInvocation.selector;
if ([Person respondsToSelector:s数据结构严蔚敏第二版课后答案el]) { //判别Person类ios14政策是否能够照顾sel
[anInvocation invoke数据结构c言语版WithTarget:Pe苹果12rson.classobjective clauses]; // 若能够照顾,则将音讯转发给其它政策处理
} else {
[anInvocation doesNotRecognizeSelectorios模拟器:sel];//若依然无法照顾,则报错:找不到办法
}
}
@end

打印效果:

2021-05-11 16:40:10.119025+0800 LoadInitializeDemo[93832:22523ios8备忘录30] person will wake up...

能够看到,咱们在+forwardingInvocation:办法里面让Peron政策去实施了personWakeup函数

已然-forwardingTargetForSelector:-forwardingInvocation:都能够将消ios最好玩的手游息转发给其它政策处理,那么两者差异在哪?
差异就在于-forwardingTargetForSelector:只能将音讯转发给一个政策,而 -forwardingInvocation:能够将音讯转发给多个方苹果官网

以上便是Ru苹果手机ntime音讯转发的整个流程

结合之前讲的3.音讯机制的基本原理,就构成ios14桌面布局图片了整个音讯苹果12发送及转发的流程,下面objective c语法咱们来总结下整个流程

6. 音讯发送一级转发机制总结

调用[receiver selector]后,进行的流程:

  1. 编译阶段:[rec数据结构教程第5版李春葆答案eiver selector]办法被编译器转换为:
    1. objc_msgSend(receiver, selector)(不带参数)
    2. objc_msgSend(rec苹果8eiver,selector, org1, org2, ...)(带参数)
  2. 作业时阶段:ios14音讯接收者receiveios14.4.1更新了什么r寻觅对应的selector
    1. 经过receiverisa指针找到receiverClass
    2. 在Class的cache(办法缓存)的散列表中寻觅对应的IMP(办法结束)
    3. 假定objective clauses是什么意思cache(办法缓存)中没有音讯机制mq找到对应的IMP(办法结束)数据结构与算法则持续在Class(类)methodLists中寻觅对应的selector,假定找到,填充到cache(办法缓存)中,并回来selector
    4. 假定在class(类)ios14桌面布局图片中没有找到这个selector,就持续在它的superclass(父类)中找
    5. 一旦找到对应的selector,直接指向receiver对应的selector办法结束的IMP(办法结束)
    6. 若找不到对应的selectorRuntime体系进入音讯转发机制

3.作业时音讯转发阶段:

  1. 动态解析:经过重写resolveInstanceM数据结构严蔚敏第二版课后答案ethodresolveClios退款assMethod,运音讯机制和事情机制class_addMethod动态增加办法
  2. 音讯接收者音讯机制结构重定向:假定上一步没有增加其它函数结束,可在当时政策中运用forwardingTargetForSelector将音讯的接音讯机制面试题收者转给其它政策
  3. 音讯重定数据结构c言语版向: 假定上一步没有回来值为nil,回来了一个NSMethodSignature政策(函数签名),Runtime体系就会创立一个NSIncovation政策音讯机制mq,并经过forwardingInvocation:音讯告诉当时政策音讯机制mq音讯机制原理给予此次音讯发送毕竟顺次寻觅IMP的机遇
  4. 假定methodSignationForSelector回来nil,则Runtime体系就会宣告doesNotRecoginzerSelector:音讯,程序也就溃散了

参看:

  1. Objective-C Runtime 苹果官方文档
  2. ObiOSjective-C Runtime Programming Guide
  3. 『Runtime』详解(一)根底知识