面试题答案
一键面试- 从运行时机制角度分析类的方法列表变化:
- 隐藏方法声明(比如通过在
@implementation
中直接实现方法而不在@interface
中声明),在运行时类的方法列表仍然会包含这个方法。Objective - C运行时是基于动态绑定机制的,方法的调用并不依赖于编译时的声明,只要方法在运行时能在类的方法列表中找到,就可以被调用。所以即使方法声明隐藏了,运行时类的方法列表还是会正常添加这个方法,就如同正常声明并实现的方法一样。
- 隐藏方法声明(比如通过在
- 通过运行时函数动态调用隐藏声明的方法(假设有两个整型参数并返回一个
NSString
对象):
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@end
@implementation MyClass
// 隐藏声明的方法
- (NSString *)hiddenMethodWithParam1:(int)param1 param2:(int)param2 {
return [NSString stringWithFormat:@"Params: %d, %d", param1, param2];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyClass *obj = [[MyClass alloc] init];
SEL methodSelector = NSSelectorFromString(@"hiddenMethodWithParam1:param2:");
Method method = class_getInstanceMethod([obj class], methodSelector);
if (method) {
// 定义函数指针类型
typedef NSString *(*MethodIMP)(id, SEL, int, int);
MethodIMP methodIMP = (MethodIMP)method_getImplementation(method);
NSString *result = methodIMP(obj, methodSelector, 10, 20);
NSLog(@"%@", result);
}
}
return 0;
}
在上述代码中:
- 首先通过
NSSelectorFromString
获取方法选择器。 - 然后使用
class_getInstanceMethod
从类中获取方法。 - 如果获取到方法,通过
method_getImplementation
获取方法的实现,将其转换为合适的函数指针类型,最后调用该函数指针并传入对象、方法选择器以及两个整型参数,从而实现对隐藏声明方法的动态调用。