iOS面试关于runtime

简介: iOS面试关于runtime

现在面试说几句就离不开Runtime,下面我将写一些简单的Runtime的概念,一方面复习巩固知识,另一方面希望读者能够有所收获。


Runtime是Objective-C中非常强大和灵活的运行时系统,它提供了一组API来动态地创建、修改、查询类和对象,支持消息发送、方法交换、动态添加方法等高级特性。下面,我们将以实际代码案例的形式,介绍Runtime的具体用法。

动态添加方法

动态添加方法是Runtime的一个重要特性之一,它允许我们在运行时动态地为一个类添加新的方法。下面是一个简单的例子:

#import <objc/runtime.h>
@interface MyClass : NSObject
@end
@implementation MyClass
@end
void dynamicMethodIMP(id self, SEL _cmd)
{
    NSLog(@"添加的方法已经被调用");
}
int main(int argc, char * argv[]) {
    @autoreleasepool {
        MyClass *myClass = [[MyClass alloc] init];
        class_addMethod([myClass class], @selector(dynamicMethod), (IMP) dynamicMethodIMP, "v@:");
        if ([myClass respondsToSelector:@selector(dynamicMethod)]) {
            [myClass performSelector:@selector(dynamicMethod)];
        } else {
            NSLog(@"方法未被添加");
        }
    }
    return 0;
}

在这个例子中,我们首先定义了一个MyClass类,并在运行时动态地为它添加了一个名为dynamicMethod的方法。我们使用class_addMethod函数来添加方法,它需要传入一个类对象、一个方法选择器、一个方法的实现和一个方法签名。在这个例子中,我们使用了一个名为dynamicMethodIMP的函数作为方法的实现,它打印一条消息。最后,我们通过检查对象是否响应dynamicMethod方法来判断方法是否已经被添加,并使用performSelector方法来调用它。

方法交换

方法交换是Runtime的另一个重要特性,它允许我们在运行时动态地交换两个方法的实现。下面是一个简单的例子:

#import <objc/runtime.h>
@interface MyClass : NSObject
- (void)originalMethod;
@end
@implementation MyClass
- (void)originalMethod {
    NSLog(@"原始方法已经被调用");
}
@end
@implementation MyClass (Category)
- (void)swizzledMethod {
    NSLog(@"交换后的方法已经被调用");
    [self swizzledMethod];
}
@end
int main(int argc, char * argv[]) {
    @autoreleasepool {
        MyClass *myClass = [[MyClass alloc] init];
        Method originalMethod = class_getInstanceMethod([MyClass class], @selector(originalMethod));
        Method swizzledMethod = class_getInstanceMethod([MyClass class], @selector(swizzledMethod));
        method_exchangeImplementations(originalMethod, swizzledMethod);
        [myClass originalMethod];
    }
    return 0;
}

在这个例子中,我们首先定义了一个MyClass类,并在它的Category中添加了一个名为swizzledMethod的方法。我们使用method_exchangeImplementations函数来交换originalMethod和swizzledMethod的实现。最后,我们使用originalMethod方法来调用原始的方法,但实际上它会调用被交换后的swizzledMethod。

消息转发

消息转发是Runtime的另一个重要特性,它允许我们在运行时处理未知消息或方法。下面是一个简单的例子:

#import <objc/runtime.h>
@interface MyClass : NSObject
@end
@implementation MyClass
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    NSLog(@"消息转发已经被触发");
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
@end
int main(int argc, char * argv[]) {
    @autoreleasepool {
        MyClass *myClass = [[MyClass alloc] init];
        [myClass performSelector:@selector(unknownMethod)];
    }
    return 0;
}

在这个例子中,我们首先定义了一个MyClass类,并重写了forwardInvocation和methodSignatureForSelector方法。当对象收到一个未知的消息时,它会触发forwardInvocation方法。我们还需要重写methodSignatureForSelector方法来返回一个合法的方法签名,这是消息转发的必要步骤。最后,我们使用performSelector方法来调用一个名为unknownMethod的未知方法,这会触发消息转发机制并调用forwardInvocation方法。

上述代码案例展示了Runtime的一些常用特性和API的用法,包括动态添加方法、方法交换和消息转发,献丑了各位。


相关文章
|
9月前
|
安全 开发工具 数据安全/隐私保护
iOS-面试之你做过支付没有?
iOS-面试之你做过支付没有?
53 0
|
9月前
|
设计模式 敏捷开发 前端开发
iOS面试
iOS面试
80 0
|
9月前
|
存储 缓存 编译器
iOS面试原理篇
iOS面试原理篇
40 0
|
10月前
|
API
15-iOS之Runtime常用API以及使用
15-iOS之Runtime常用API以及使用
63 0
|
存储 程序员 编译器
iOS每天让ChatGPT出五道面试题(25)
iOS每天让ChatGPT出五道面试题(25)
202 0
|
存储 缓存 编译器
iOS每天让ChatGPT出五道面试题(24)
iOS每天让ChatGPT出五道面试题(24)
143 0
|
算法 安全 Swift
iOS每天让ChatGPT出五道面试题(23)
iOS每天让ChatGPT出五道面试题(23)
206 0
|
存储 安全 Java
iOS每天让ChatGPT出五道面试题(22)
iOS每天让ChatGPT出五道面试题(22)
183 0
|
存储 缓存 安全
iOS每天让ChatGPT出五道面试题(21)
iOS每天让ChatGPT出五道面试题(21)
156 0
|
存储 前端开发 网络安全
iOS每天让ChatGPT出五道面试题(20)
iOS每天让ChatGPT出五道面试题(20)
116 0