iOS开发之Runtime初探

Runtime详解——iOS开发中的黑魔法 简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的。比如: [receiver message]; // 底层运行时会被编译器转化为: objc_msgSend(receiver, selector) // 如果其还有参数比如: [receiver message:(id)arg...]; // 底层运... 阅读详情

一:基础概念

RunTime简称运行时,就是系统在运行的时候的一些机制,其中最主要的是消息机制。
对于C语言,函数的调用在编译的时候会决定调用哪个函数,编译完成之后直接顺序执行,无任何二义性。
OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。
只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用。

Objective-C 从三种不同的层级上与 Runtime 系统进行交互,分别是:
1、通过 Objective-C 源代码;
2、通过 Foundation 框架的NSObject类定义的方法;
3、通过对 runtime 函数的直接调用。
大部分情况下你就只管写你的Objc代码就行,runtime 系统自动在幕后辛勤劳作着。

二:runtime的具体实现

我们写的oc代码,它在运行的时候也是转换成了runtime方式运行的,更好的理解runtime,也能帮我们更深的掌握oc语言。每一个oc的方法,底层必然有一个与之对应的runtime方法。image

当我们用OC写下这样一段代码
[tableView cellForRowAtIndexPath:indexPath];
在编译时RunTime会将上述代码转化成[发送消息]
objc_msgSend(tableView, @selector(cellForRowAtIndexPath:),indexPath);

三:常见方法

1、获取属性列表
//People.h
@interface People : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSUInteger age;

@end

//People.m
@interface People() {
    NSString *aaa;
}

@property (nonatomic, strong) NSString *fatherName;

@end

@implementation People {
    NSString *bbb;
}

@end
//获取所有属性
-(void)getAllProperty {
    unsigned int count = 0;
    objc_property_t *propertyList = class_copyPropertyList([People class], &count);
    for (unsigned int i=0; i<count; i++) {
        const char *propertyName = property_getName(propertyList[i]);
        NSLog(@"property---->%@", [NSString stringWithUTF8String:propertyName]);
    }
}

打印结果:

获取属性列表

结论:
1)、不管是在.h文件中定义的属性还是在.m文件中定义的属性,都可以通过获取属性列表方法来进行获取;
2)、成员变量不同于属性,不能通过该方法来获取;
3)、先输出的是.m文件中的属性,然后才是.h文件中的属性,并且是按照属性定义的先后顺序来保存。

2、获取方法列表
//People.h
@interface People : NSObject

@property (nonatomic, strong) NSString *name;

-(void)iPrintName;
+(void)cPrintName;
@end

//People.m
@interface People() {
    NSString *aaa;
}

@property (nonatomic, strong) NSString *fatherName;

@end

@implementation People {
    NSString *bbb;
}

//-(void)printName {
//    
//}

+(void)cPrintName {

}

-(void)printAge {

}

@end
//获取方法(不包括类方法)列表
-(void)getAllMethod {
    unsigned int count = 0;
    Method *methodList = class_copyMethodList([People class], &count);
    for (unsigned int i=0; i<count; i++) {
        Method method = methodList[i];
        NSLog(@"method---->%@", NSStringFromSelector(method_getName(method)));
    }
}

获取方法列表

结论:
1)、类方法不能通过这个函数去获取到;
2)、只有在.m文件中实现了的方法才能被获取到,在.h文件中定义了,但是.m中没有实现的并不能获取到;
3)、对于使用@property定义的属性,会自动生成setter和getter方法,同样能被这个方法获取到;
4)、.m实现中还隐藏了一个.cxx_destruct也就是oc中常见delloc方法;
5)、保存顺序是优先保存用户在.m文件中实现的,其次是.m属性自动生成的getter和setter方法,然后是隐藏的delloc方法,最后是.h属性自动生成的getter和setter方法。

3、获取成员变量列表
//People.h
@interface People : NSObject {
    NSString *cccc;
}

@property (nonatomic, strong) NSString *name;

@end

//People.m
@interface People() {
    NSString *aaa;
}

@property (nonatomic, strong) NSString *fatherName;

@end

@implementation People {
    NSString *bbb;
}

@end
-(void)getAllIvar{
    unsigned int count = 0;
    Ivar *ivarList = class_copyIvarList([People class], &count);
    for (unsigned int i=0; i<count; i++) {
        Ivar myIvar = ivarList[i];
        const char *ivarName = ivar_getName(myIvar);
        NSLog(@"Ivar---->%@", [NSString stringWithUTF8String:ivarName]);
    }
}

打印结果:
获取成员变量列表

结论:
1)、成员变量的保存是从.h文件开始,然后才是.m文件中的成员变量;
2)、用@property 定义的属性,会自动生成以_开头的成员变量,也是先保存.h文件生成的,再保存.m文件生成的。


4、获取协议列表
//People.h
@protocol PeopleDelegate <NSObject>

-(void)people;

@end

@interface People : NSObject

@property (nonatomic, strong) NSString *name;
//@property (nonatomic, weak) id <PeopleDelegate> delegate;
@end

//People.m
@interface People()

@property (nonatomic, strong) NSString *fatherName;

@end

@implementation People

@end

//ViewController.m
@interface ViewController ()<PeopleDelegate,UITabBarDelegate,UITableViewDataSource>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self getProtocal];
}
@end
//获取协议列表
-(void)getProtocal {
    unsigned int count = 0;
    __unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);  //这里变成了self
    for (unsigned int i = 0; i<count; i++) {
        Protocol *myProtocal = protocolList[i];
        const char *protocolName = protocol_getName(myProtocal);
        NSLog(@"protocol---->%@", [NSString stringWithUTF8String:protocolName]);
    }
}

打印结果:

获取协议列表

结论:
1)、只要声明遵循该协议,在引用的时候,就能获取到该类包含的协议列表,哪怕你没有指定代理的对象,也没有去实现协议的方法

5、获取类方法与实例方法以及方法交换
//People.h
@interface People : NSObject

@property (nonatomic, strong) NSString *name;

-(void)printInstanceMethod;
+(void)printClassMethod;

@end

//People.m
@interface People()

@property (nonatomic, strong) NSString *fatherName;

@end

@implementation People
-(void)printInstanceMethod{
    NSLog(@"我是实例方法");
}

+(void)printClassMethod {
    NSLog(@"我是类方法");
}
@end

示例

-(void)getMethod {

    People * p1 = [[People alloc] init];

    Method m1 = class_getInstanceMethod([p1 class], @selector(printInstanceMethod));
    Method m2 = class_getClassMethod([People class], @selector(printClassMethod));
    NSLog(@"测试前:");
    [p1 printInstanceMethod];
    [People printClassMethod];

    method_exchangeImplementations(m1, m2);
    NSLog(@"测试后:");
    [p1 printInstanceMethod];
    [People printClassMethod];
}

打印结果

获取方法以及交换方法

6、添加方法

当项目中,需要继承某一个类(subclass),但是父类中并没有提供我需要的调用方法,而我又不清楚父类中某些方法的具体实现;或者,我需要为这个类写一个分类(category),在这个分类中,我可能需要替换/新增某个方法(注意:不推荐在分类中重写方法,而且也无法通过 super 来获取所谓父类的方法)。大致在这两种情况下,我们可以通过 class_addMethod 来实现我们想要的效果。参考

//Car+MyCar.h
#import "Car+MyCar.h"
#import <objc/runtime.h>

void startEngine(id self, SEL _cmd, NSString *brand) {
    NSLog(@"my %@ car starts the engine", brand);
}

@implementation Car (MyCar)

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(drive)) {
        class_addMethod([self class], sel, (IMP)startEngine, "v@:@");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

不习惯C语言代码可以替换成以下代码:

 - (void)startEngine:(NSString *)brand {
    NSLog(@"my %@ car starts the engine", brand);
 }

 + (BOOL)resolveInstanceMethod:(SEL)sel {
     if (sel == @selector(drive)) {
       class_addMethod([self class], sel, class_getMethodImplementation(self, @selector(startEngine:)), "v@:@");
       return YES;
     }
     return [super resolveInstanceMethod:sel];
 }

@end

调用:

-(void)addMethod {
    Car *c = [[Car alloc] init];
    [c performSelector:@selector(drive) withObject:@"BMW"];
}

解释:
在 Objective-C 中,正常的调用方法是通过消息机制(message)来实现的,那么如果类中没有找到发送的消息方法,系统就会进入找不到该方法的处理流程中,如果在这个流程中,我们加入我们所需要的新方法,就能实现运行过程中的动态添加了。这个流程或者说机制,就是 Objective-C 的 Message Forwarding 。
这个机制中所涉及的方法主要有两个:

+ (BOOL)resolveInstanceMethod:(SEL)sel;//实例方法
+ (BOOL)resolveClassMethod:(SEL)sel;//类方法

这个函数在 runtime 环境下,如果没有找到该方法的实现的话就会执行。第一行判断的是传入的 SEL 名称是否匹配,接着调用 class_addMethod 方法,传入相应的参数。其中第三个参数传入的是我们添加的 C 语言函数的实现,也就是说,第三个参数的名称要和添加的具体函数名称一致。第四个参数指的是函数的返回值以及参数内容。

结果:

添加方法

装逼:

一开始我以为class_addMethod和class_replaceMethod就等同于method_exchangeImplementations,但是看了下面的代码才发现,其实这俩的适用条件是不一样的,当方法没有实现的时候才能使用class_addMethod和class_replaceMethod套装,但是当方法已存在的时候,就需要使用method_exchangeImplementations,这点从if (didAddMethod)这个判定就可见一斑。

+(void)load{
    NSString *className = NSStringFromClass(self.class);
    NSLog(@"classname %@", className);
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //要特别注意你替换的方法到底是哪个性质的方法
        // When swizzling a Instance method, use the following:
        //        Class class = [self class];

        // When swizzling a class method, use the following:
        Class class = object_getClass((id)self);

        SEL originalSelector = @selector(systemMethod_PrintLog);
        SEL swizzledSelector = @selector(ll_imageName);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

Runtime博大精深,看的越深入,感觉越懵 T_T,浅显的认知,欢迎大家提意见

Demo


资料
runtime详解
runtime奇技淫巧系列

ArcGIS Runtime SDK for iOS开发之-显示你的位置 在地图上显示你的位置:        许多iOS设备如iPod touch、iPad和iPhone提供了设备的位置信息。我们知道iOS包含了一个大家都很熟悉的CoreLocation框架,该框架为我们提供了位置获取的功能,无论是通过Wi-Fi、蜂窝网络还是GPS。这个框架同时也为开发人员提供了API,使得他们能够将定位功能集成到他们的应用程序中去。       AGSmapView组建提供了一 阅读详情

相关推荐

iOS面试中经常问的点 - RunTime

一. RunTime简介RunTime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制。对于C语言,函数的调用在编译的时候会决定调用哪个函数,如果调用未实现的函数就会报错。对于OC语言,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声...

程序猿 2326

iOS开发-------初探运行时runtime

对于iOS的开发者,相信Objc的RunTime机制肯定都听说过,了解RunTime的机制,对自己的提高不言而喻,最近在一直学习RunTime机制,对此写下点学习过程的收获,以便以后查阅,也方便理解,本人研究RunTime时间不长,如果有理解不对的地方也请告知,共同进步。      什么叫RunTime呢,大家也都知道Objc的底层是C语言完成的,在运行的时候,会将Objc的代码转换成C

RITL_Y 1096

iOS高级开发工程师面试——RunTime

语言是一门动态语言。它把一些决策从编译阶段链接阶段推迟到运行时阶段,实现该机制的基础就是runtime(又叫作运行时)。Runtime 提供的接口基本都是 C 语言,源码由 C\C++\汇编语言编写。Runtime API 为 Objective-C 语言的动态属性提供支持,充当一种用于 Objective-C 语言的操作系统,使得该语言正常运转工作。OC中的对象指向的是一个指针类型,;从它的结构体中可以看出,它包括一个isa指针,指向的是这个对象的类对象,一个对象实例就是通过这个isa找到它自己的。

wahkim的博客 1139

iOS 开发 Runtime到底是什么?

Runtime到底是什么?这个问题一直以来都困扰着大家的,做iOS开发,天天和Object-c打交道,却对runtime到底是什么感觉到很费解? 那么我们就先了解熟悉的东西:Object-C做iOS开发做的最基本的操作:类,对象,属性,方法,—无论你做什么功能都离开这四个最基本的东东,包括网络请求,代理协议,通知,block,多线程,KVC/KVO,内存管理等等.都是用哪个类创建哪个对象,修改类的属

高级软件开发工程师--周玉的博客 1831

iOS开发:Runtime解析

Runtime,又叫运行时,是一套关于底层的C语言API,为iOS内部的核心之一,我们在编写OC代码的时候,底层都是基于它来实现的。

全沾软贱开发攻城狮 1万+

11-4 AEB 算法原理及系统组成

本专题旨在探讨如何利用仿真软件开发自动紧急制动系统AEB,主要通过整理开发流程,实现从需求到验证的全流程掌握,为后续开发提供支持;同时,研究了如何在汽车自动驾驶仿真工具中开发自己的算法,并解决了从ISO、E-CNAP、GB/T以及交通法规等提炼出功能需求的问题,以快速实现原型模型的开发。本专题重点讲解了AEB的工作原理、系统/软件架构和需求、算法模型及实现、CCRs/CCRb/CCRm建模与仿真、VRU-AEB-B/P/M建模与仿真,同时还提供了测试用例,期待将AEB算法成功地产品化。

AIgraphX 8547

IOS 开发— Runtime 机制

IOS 开发— Runtime 机制 Runtime 底层原理与应用 Runtime 又叫运行时,是一套IOS底层的C语言API。Objective-C在运行时被转化为C语言的API。Objective-C时一门动态语言,在代码运行才进行处理和编译。因此需要一个运行时系统(Runtime System)来处理编译后的Code。 Runtime 基本是用C和汇编实现的,苹果和GNU各自维护一套Run...

HiroGuo 的博客 571

深入解析USB3.0一致性测试的关键技术与实践指南

本文深入解析了USB3.0一致性测试的核心技术与实践指南。文章阐述了测试如何确保设备在5Gbps高速传输下的信号完整性、电源管理合规性及协议兼容性,并提供了从测试系统搭建到完整流程执行的实战经验,帮助工程师有效应对高速信号、电源与兼容性三大核心挑战。

weixin_29164091的博客 278

【iOS开发】—— 初学Runtime

Runtime的特性主要是消息(方法)传递,如果消息(方法)在对象中找不到,就进行转发。Objective-C 扩展了 C 语言,并加入了面向对象特性和 Smalltalk 式的消息传递机制。而这个扩展的核心是一个用 C 和 编译语言 写的 Runtime 库。它是 Objective-C 面向对象和动态机制的基石。Objective-C 是一个动态语言,这意味着它不仅需要一个编译器,也需要一个运行时系统来动态的创建类和对象、进行消息传递和转发。

qq_72437394的博客 1151

WRF模型下中国土地利用数据替换USGS-24分类的完整实践指南

本文提供了在WRF模型中,将中国土地利用数据替换默认USGS-24分类的完整实践指南。详细阐述了替换下垫面数据的必要性,并分步讲解了数据准备、坐标转换、分类体系重映射、格式转换及配置文件修改等核心操作,旨在帮助用户提升针对中国区域的模拟精度。

salt的博客 777

联想服务器ThinkSystemRAID阵列设置教程

关注我不迷路,全是干货! 以联想ThinkSystemSR530为例子进行示范。 开机点按【F1】 点击——【UEFI设置】 依次点击——【系统设置】——【存储】 点击——【RAID卡】 PS:本次服务器配置的是730-8i 阵列卡,按实际情况选中需要设置的阵列卡即可。 点击——【Main Menu】 点击——【Configuration Management】 点击——【Create Virtual Drive】 点击——【Select RAID Leve..

littlelotusK的博客 2万+

iOS开发之Runloop和Runtime

RunLoop 对于一个iOS开发者,如果你的水平只是停留在会用API的级别,那说明你与大神还是慢慢长路,本文章大家一块学习一些深层次的东西,RunLoop和Runtime。Runloop官方文档 你肯定写过一个按钮点击事件,点击界面上的一个按钮,这个时候就会有对应的按钮响应事件发生。给我们的感觉就像应用一直处于随时待命的状态,在没人操作的时候它一直在休息,在让它干活的时候,它就能立刻响应。其实

逝水无情的博客 3233

SVDD和OCSVM的比较

OCSVM(one class support vector machine)即单类支持向量机,最先提出的文献为:Estimating the support of a high-dimensional distribution.该模型 将数据样本通过核函数映射到高维特征空间,使其具有更良好的聚集性,在特征空间中求解一个最优超平面实现目标数据与坐标原点的最大分离,如图1: 坐标原...

qq_33880788的博客 1万+

iOS runtime 初探

大家好mark qq:1124728522 欢迎大家与我多多交流。

iOS_mark的博客 544

MATLAB实战:5步搞定GNSS单点定位解算(附完整代码)

本文提供了一份基于MATLAB的GNSS单点定位实战指南。通过5个核心步骤,详细讲解了如何从卫星坐标和伪距观测值出发,利用最小二乘迭代算法,构建并实现一个完整的单点定位解算器。文章附有完整代码,并涵盖精度评估与结果分析,适合GNSS初学者和MATLAB用户快速上手实践。

a2b3c4d5e的博客 249

YOLOv11损失函数进阶:融合SmoothL1与FocalLoss,让检测精度再涨10%的实战教程

在YOLOv11的这里的beta参数控制“L1与L2的过渡阈值”,默认设为1.0即可兼容多数场景。同样在# 计算动态alpha(基于类别样本数,需提前统计self.class_counts)# 交叉熵基础# FocalLoss权重else:使用前需统计数据集的(每个类别的样本数),并传入的alpha参数。损失函数是YOLOv11精度的“灵魂”——SmoothL1让边界框回归“稳、准、狠”,改进FocalLoss让类别分类“雨露均沾”。从代码改造到实战落地,本教程已为你搭建了一条精度跃升的路径。

m0_64661770的博客 212

eclipse中没有runtime environments_iOS开发——RunTime总结篇

基础路径图:在学习 RunTime 的基础时, 我们要搞清楚一些重要的东西, 一些专业术语:SELidClassMethodIvarIMPCacheProperty我们可以从这些东西里获取到指定类的所有信息, 无论是公开的, 还是私有的, 全部都可以拿到, 并且操作.作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:413038000,不管你是大牛还是小白都欢迎入驻...

weixin_39756336的博客 468

Windows Server 2019 服务器一天之中内存利用率越来越高直到死机,疑似内存泄漏

环境: 华为桌面云虚拟机 Windows Server 2019 版本1809 OS内部版本17763.107 问题描述: Windows Server 2019服务器 一天之中内存利用率越来越高直到死机,不断扩容内存从10G到16G一重启就正常然后慢慢又循环,连续几天都这样,疑似内存泄漏 内存泄漏是什么? 内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪

本博客,博文仅代表个人操作经验,不能完全解决你的问题,仅供参考,佛系回复。 5392

ios c语言编译环境搭建,iOS开发之runtime(一):runtime调试环境搭建

本系列博客是本人的源码阅读笔记,如果有 iOS 开发者在看runtime的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论 引言相信接触过iOS的同学对runtime或多或少都有耳闻。 创建一个对象:[[...

weixin_35843410的博客 388

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

iOS开发:认识一下Runtime

runtime(简称运行时),是一套纯C(C和汇编)编写的API。而OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制 objc_msgSend。

wuwuFQ的博客 1164

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Runtime在iOS开发中的实际应用

运行时的文章一直被同学们热炒,当然现在面试中也都喜欢问道,当大伙说的头头是道时候,可到真正的项目中几乎局限只会关联对象或者MethodSwizzling奉为神剑到处挥砍,开发毕竟不能纸上谈兵,实践出真知,介绍目前在项目中runtime的具体使用,真切希望和各位同学探讨。(个人的使用)使用 runtime 为 UIButton 分类修改响应位置 使得点击范围扩大https://github.com/...

qq_41597968的博客 1175

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【iOS】——Runtime学习

iOS的Runtime,通常称为Objective-C Runtime,是一个C语言库,包含了很多底层的纯C语言API。,它是Objective-C语言动态特性的基石。这个系统在程序运行时提供了一系列强大的功能,允许我们在应用运行过程中动态地操作类和对象,执行诸如检查和改变对象、交换方法实现、动态添加方法或属性等操作。高级编程语言想要成为可执行文件需要先编译为汇编语言再汇编为机器语言,机器语言也是计算机能够识别的唯一语言,但是OC并不能直接编译为汇编语言,而是要先转写为纯C语言再进行编译和汇编的操作,

m0_73974920的博客 2735

IOS开发之Runtime(三)

第2阶段: 有一个bool类型的变量标记是否进入过动态方法解析阶段,如果为true进入第3阶段消息转发,如果为false,调用 +resolveInstanceMethod: 或者+resolveClassMethod: 方法来动态解析方法,标记为已经动态解析,再次进入第1阶段消息发送,如果走完第1个阶段还是没有解决,此时这个bool类型的变量为true,直接进入第3阶段消息发送。forwardingTargetForSelector:方法,有实例方法也有类方法。objc_msgSend的汇编。

m0_63640651的博客 589

.NET Runtime移动开发:iOS/Android原生集成

你是否曾面临这样的困境?需要在iOS和Android平台上开发高性能应用,但又不希望维护两套完全不同的代码库?传统的跨平台方案往往在性能、原生体验和开发效率之间难以平衡。.NET Runtime通过先进的AOT(Ahead-of-Time)编译技术和原生集成能力,为移动开发提供了革命性的解决方案。 ## .NET移动开发架构解析 ### 核心架构概览 ```mermaid graph TD ...

gitblog_01097的博客 900

iOS之runtime

参考: https://www.jianshu.com/p/9e975a1cab93 https://www.jianshu.com/p/6ebda3cd8052 https://blog.ibireme.com/2013/11/26/objective-c-messaging/ 本文不是讲解,只做面试梳理。 1、isa指针 //对象 struct objc_object { ...

ihoudf 532

iOS开发——RunTime总结篇

基础路径图: 在学习 RunTime 的基础时, 我们要搞清楚一些重要的东西, 一些专业术语: SEL id Class Method Ivar IMP Cache Property 我们可以从这些东西里获取到指定类的所有信息, 无论是公开的, 还是私有的, 全部都可以拿到, 并且操作. 作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:413038000,不管你是大牛还是小白都欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流

原来是泽镜的博客 297
上一篇: iOS五种页面传值方式
下一篇: iOS实战之调起QQ加群页和临时会话页
SuAdrenine
博客等级 码龄11年 6粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值