OC最实用的runtime总结,面试、工作你看我就足够了!

iOS Runtime理解和应用场景 为了关联属性和其对应的存取方法,需要定义一个全局唯一的键值。 阅读详情

引言

Objective-C是一门面向对象的编程语言,在iOS开发中被广泛使用。而在Objective-C中,runtime是其核心之一,为开发者提供了许多强大的特性。本文将总结OC中最实用的runtime特性,包括动态添加方法、动态交换方法、获取类的属性和方法列表、动态创建类和对象等,并结合实际案例演示其用法,帮助读者更好地理解和应用runtime。

Image

1. 动态添加方法

在OC中,我们可以使用runtime动态地为一个类添加方法。这在某些情况下非常有用,比如在运行时根据条件来决定是否添加某个方法,或者在运行时根据用户的操作来动态添加方法。

步骤

  1. 导入<objc/runtime.h>头文件。

  2. 使用class_addMethod函数为类添加方法。

代码示例

假设我们有一个Person类,但是它没有一个sayHello方法。我们可以使用runtime在运行时动态为Person类添加一个sayHello方法。

\#import <objc/runtime.h>



@interface Person : NSObject



@end



@implementation Person



@end



void sayHello(id self, SEL _cmd) {

 NSLog(@"Hello!");

}



int main(int argc, const char * argv[]) {

 @autoreleasepool {

•    Person *person = [[Person alloc] init];

•    // 动态添加sayHello方法

•    class_addMethod([Person class], @selector(sayHello), (IMP)sayHello, "v@:");

•    // 调用动态添加的sayHello方法

•   [person performSelector:@selector(sayHello)];

}

 return 0;

}

运行这段代码,我们会发现Person类成功地动态添加了sayHello方法,并成功调用了它。

2. 动态交换方法

使用runtime,我们还可以动态交换两个方法的实现。这在某些情况下非常有用,比如在调试或者实现A/B测试时,我们可能需要替换某个方法的实现。

步骤

  1. 导入<objc/runtime.h>头文件。

  2. 使用method_exchangeImplementations函数交换两个方法的实现。

代码示例

假设我们有一个Calculator类,它有两个方法add:(NSInteger)a to:(NSInteger)bsubtract:(NSInteger)a from:(NSInteger)b,我们可以使用runtime在运行时交换这两个方法的实现。

#import <objc/runtime.h>



@interface Calculator : NSObject



- (NSInteger)add:(NSInteger)a to:(NSInteger)b;

- (NSInteger)subtract:(NSInteger)a from:(NSInteger)b;



@end



@implementation Calculator



- (NSInteger)add:(NSInteger)a to:(NSInteger)b {

 return a + b;

}



- (NSInteger)subtract:(NSInteger)a from:(NSInteger)b {

 return b - a;

}



@end



int main(int argc, const char * argv[]) {

 @autoreleasepool {

•    Calculator *calculator = [[Calculator alloc] init];

•    NSInteger result1 = [calculator add:5 to:10];

•    NSLog(@"Result1: %ld", (long)result1); // Output: Result1: 15

•    

•    // 动态交换add:to:和subtract:from:方法的实现

•    Method addMethod = class_getInstanceMethod([Calculator class], @selector(add:to:));

•    Method subtractMethod = class_getInstanceMethod([Calculator class], @selector(subtract:from:));

•    method_exchangeImplementations(addMethod, subtractMethod);

•    

•    NSInteger result2 = [calculator add:5 to:10];

•    NSLog(@"Result2: %ld", (long)result2); // Output: Result2: 5

}

 return 0;

}

在上述代码中,我们成功地动态交换了add:to:subtract:from:方法的实现,从而在运行时改变了方法的行为。

3. 获取类的属性和方法列表

使用runtime,我们可以在运行时获取一个类的属性列表和方法列表,这为我们提供了更多的灵活性和动态性。

步骤

  1. 导入<objc/runtime.h>头文件。

  2. 使用class_copyPropertyList函数获取类的属性列表。

  3. 使用class_copyMethodList函数获取类的方法列表。

代码示例

假设我们有一个Person类,我们可以使用runtime在运行时获取它的属性列表和方法列表。

#import <objc/runtime.h>



@interface Person : NSObject



@property (nonatomic, strong) NSString *name;

@property (nonatomic, assign) NSInteger age;



- (void)sayHello;



@end



@implementation Person



- (void)sayHello {

 NSLog(@"Hello, my name is %@ and I am %ld years old.", self.name, (long)self.age);

}



@end



int main(int argc, const char * argv[]) {

 @autoreleasepool {

•    Person *person = [[Person alloc] init];

•    person.name = @"John";

•    person.age = 30;

•    

•    // 获取属性列表

•    unsigned int propertyCount;

•    objc_property_t *properties = class_copyPropertyList([Person class], &propertyCount);

•    for (unsigned int i = 0; i < propertyCount; i++) {

•      objc_property_t property = properties[i];

•      const char *propertyName = property_getName(property);

•      NSString *name = [NSString stringWithUTF8String:propertyName];

•      NSLog(@"Property: %@", name);

•   }

•    free(properties);

•    

•    // 获取方法列表

•    unsigned int methodCount;

•    Method *methods = class_copyMethodList([Person class], &methodCount);

•    for (unsigned int i = 0; i < methodCount; i++) {

•      Method method = methods[i];

•      SEL methodName = method_getName(method);

•      NSString *name = NSStringFromSelector(methodName);

•      NSLog(@"Method: %@", name);

•   }

•    free(methods);

}

 return 0;

}

在上述代码中,我们成功地获取了Person类的属性列表和方法列表,并输出了它们的名称。

4. 动态创建类和对象

在runtime中,我们还可以动态地创建类和对象。这在一些需要动态生成类和对象的场景下非常有用,比如在运行时根据用户的操作动态生成新的类和对象。

步骤

  1. 导1. 导入<objc/runtime.h>头文件。

  2. 使用objc_allocateClassPair函数创建一个新类。

  3. 使用class_addMethod函数为新类添加方法。

  4. 使用objc_registerClassPair函数注册新类。

  5. 使用class_createInstance函数创建新类的实例。

代码示例

假设我们需要在运行时动态创建一个新的Person类,并为该类添加一个sayHello方法。

#import <objc/runtime.h>



@interface Person : NSObject



@end



@implementation Person



@end



void sayHello(id self, SEL _cmd) {

 NSLog(@"Hello, I am a dynamic Person!");

}



int main(int argc, const char * argv[]) {

 @autoreleasepool {

•    // 动态创建一个新的Person类

•    Class newClass = objc_allocateClassPair([NSObject class], "DynamicPerson", 0);

•    

•    // 为新类添加sayHello方法

•    class_addMethod(newClass, @selector(sayHello), (IMP)sayHello, "v@:");

•    

•    // 注册新类

•    objc_registerClassPair(newClass);

•    

•    // 创建新类的实例并调用sayHello方法

•    id dynamicPerson = [[newClass alloc] init];

•   [dynamicPerson performSelector:@selector(sayHello)];

}

 return 0;

}

在上述代码中,我们成功地动态创建了一个名为DynamicPerson的新类,并为其添加了sayHello方法。最后,我们创建了DynamicPerson类的实例,并成功调用了sayHello方法。

结论

OC的runtime是iOS开发中非常强大且实用的特性,它为开发者提供了许多灵活和动态的操作。在本文中,我们总结了OC中最实用的runtime特性,包括动态添加方法、动态交换方法、获取类的属性和方法列表、动态创建类和对象等,并通过实际代码示例演示了它们的用法。掌握了这些runtime特性,开发者可以更好地应对各种复杂的场景,提高开发效率,使代码更加灵活和强大。希望本文对读者有所帮助,让你在面试和工作中信心满满!

 

iOS面试题--Runtime runtime 对注册的类,会进行内存布局,从一个粗粒度的概念上来讲,这时候会有一个 hash 表,这是一个全局表,表中是用 weak 指向的对象内存地址作为 key,用所有指向该对象的 weak 指针表作为 value。当此对象的引用计数为 0 的时候会 dealloc,假如该对象内存地址是 a,那么就会以 a 为 key,在这个 weak 表中搜索,找到所有以 a 为键的 weak 对象,从而设置为 nil。为这种属性设置新值时,设置方法既不持有新值(新指向的对象),也不释放旧值(原来指向的对象)。 阅读详情

相关推荐

UE5游戏逆向实战:用FModel提取.pak文件中的3D模型(附Dumper-7避坑指南)

本文详细介绍了如何使用FModel工具从UE5游戏的.pak文件中提取3D模型,并提供了Dumper-7的避坑指南。内容涵盖FModel工具链配置、UE5特有的unversioned properties问题解决方案、Dumper-7实战流程以及模型后处理技巧,帮助开发者高效获取游戏资产。

weixin_30872499的博客 378

OC Runtime开源代码

RunTime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中主要的是消息机制。 OC Runtime开源代码提供OC Runtime整个实现的源码,研读之后,对理解OC底层原理非常有帮助

【计算摄影】相机成像原理:从光到JPEG图像

本文我们将从基本的相机成像原理开始论述,再讨论光线进入相机后,经过一系列处理成为JPEG图像的大致流程。

qq_35149975的博客 2万+

OC底层学习-Runtime

OC底层学习-Runtime1. 概述2.Runtime之 isa指针2. 面试题 1. 概述 Objective-C是一门动态性比较强的编程语言,跟C、C++等语言有着很大的不同 Objective-C的动态性是由Runtime API来支撑的 Runtime API提供的接口基本都是C语言的,源码由C\C++\汇编语言编写 2.Runtime之 isa指针 要想学习Runtime,首先需要了解底层的一些常用的数据结构,比如isa指针 在arm64架构之前,isa就是 一个普通的指针,储存着Cla

yong_19930826的博客 1300

OC runtime 运行时详解

一、简介 1.1 什么是Runtime Runtime是一套底层纯C语言API,我们编写的OC代码终都会被编译器转化为运行时代码,通过消息机制决定函数调用方式,这也是OC作为动态语言使用的基础。 1.2 消息机制的基本原理 在Object-C的语言中,对象方法调用都是类似[receiver selector] 的形式,其本质:就是让对象在运行时发送消息的过程。 而方法调用[receiver selector]分为两个过程: 编译阶段 [receiver selector] 方法被编译器转化,分为.

Rey的技术博客 1420

OC -- Runtime了解一下

一、Runtime机制 1 &gt; OC是一门面向对象的动态语言,所以具有面向对象的特性,如封装、继承、多态、动态特性表现在动态类型、动态加载、动态绑定。他会将一些工作放在运行时处理,很多类和成员变量在编译期是不知道的,那么仅仅在编译期是不够的,需要一个运行时的系统来处理编译后的代码。这些都是由底层的API -- runtime机制所支持的,是指在一个程序运行时候的状态,OC代码在程序运行时...

ningn111的博客 621

OC——Runtime

详谈Runtime机制

yinhaijing_ss的专栏 500

OC实用runtime总结

前言 runtime的资料网上有很多了,部分有些晦涩难懂,我通过自己的学习方法总结一遍,主要讲一些常用的方法功能,以实用为主,我觉得用到印象才是深刻的,并且后两个demo也是MJExtension的实现原理,面试的时候也可以多扯点。 另外runtime的知识还有很多,想要了解更多可以看我翻译的官方文档(有点枯燥),本文的demo下载地址 什么是runtimeruntimeOC

viiimaus的博客 7878

2019年实用runtime面试总结

相信有过面试经验的iOS开发者都知道在iOS开发的面试中,runtime是属于必问的几个点之一,但是平时我们工作中接触到它的机会真的少之又少,很多人一直都认为runtime只是用来装13神器而已。但是随着对IOS的深度学习和日常工作中发现runtime真的是相当好用,但是也没有那么神秘不测! 什么是runtimeruntimeOC底层的一套C语言的API(引入 或),编译器终都会将OC...

weixin_34378045的博客 149

iOS-OC实用runtime总结

前言 runtime的资料网上有很多了,部分有些晦涩难懂,我通过自己的学习方法总结一遍,主要讲一些常用的方法功能,以实用为主,我觉得用到印象才是深刻的,并且后两个demo也是MJExtension的实现原理,面试的时候也可以多扯点。 另外runtime的知识还有很多,想要了解更多可以看我翻译的官方文档(有点枯燥),本文的demo下载地址 什么是runtimeruntimeOC底层的一套C语言的API(引入 <objc/runtime.h> 或<objc/message.

MinggeQingchun的博客 457

OC实用runtime总结.

前言 runtime的资料网上有很多了,部分有些晦涩难懂,我通过自己的学习方法总结一遍,主要讲一些常用的方法功能,以实用为主,我觉得用到印象才是深刻的,并且后两个demo也是MJExtension的实现原理,面试的时候也可以多扯点。 另外runtime的知识还有很多,想要了解更多可以看我翻译的官方文档(有点枯燥),本文的demo下载地址 什么是runtimeruntimeOC

zhonggaorong的专栏 2712

西藏2016《西藏自治区建设工程预算定额》宣贯材料.pdf

西藏2016《西藏自治区建设工程预算定额》宣贯材料.pdf

上一篇: 搭建:离线部署 CDH 5.12.1 及部署 Hadoop 集群服务
下一篇: iOS的小技巧总结,绝对有你想要的
good7ob
博客等级 码龄4年 498粉丝 · 250原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值