Objective-C Runtime 賦予了極強的動態能力:運行時獲取/修改類信息、增刪方法屬性、實現 Hook、消息轉發等。本文總結六大核心要點,附實戰代碼示例。
實現類似 Windows Hook 的效果:截獲系統方法調用,注入自定義邏輯(如日誌、埋點)。
IMP originIMP;
NSString *MyUppercaseString(id self, SEL _cmd) {
NSLog(@"begin uppercaseString");
NSString *str = originIMP(self, _cmd); // 調用原實現
NSLog(@"end uppercaseString");
return str;
}
- (void)testReplaceMethod {
Class cls = [NSString class];
SEL sel = @selector(uppercaseString);
originIMP = [NSString instanceMethodForSelector:sel]; // 保存原 IMP
class_replaceMethod(cls, sel, (IMP)MyUppercaseString, NULL); // 替換
NSString *s = @"hello world";
NSLog(@"%@", [s uppercaseString]); // 觸發 Hook
}
輸出:begin → end → HELLO WORLD。
class_addMethod 同理可動態新增方法。
當對象無法響應 Selector 時,將其轉發給其他對象處理,避免崩潰,支援裝飾者模式。
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (aSelector == @selector(uppercaseString))
return @"hello world"; // 返回 NSString 實例處理
return [super forwardingTargetForSelector:aSelector];
}
測試:[[CA new] performSelector:@selector(uppercaseString)] → 輸出 HELLO WORLD。
類方法,在無法響應 Selector 時動態添加實現。優先於 forwardingTargetForSelector 觸發。
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
if (aSEL == @selector(t)) {
class_addMethod([self class], aSEL, (IMP)dynamicMethodIMP, "v@:");
return YES; // 添加成功,後續不再轉發
}
return [super resolveInstanceMethod:aSEL];
}
調用順序:
1. 程序啟動早期觸發 resolveInstanceMethod
2. 實際調用時觸發 forwardingTargetForSelector
3. 若轉發失敗(返回 nil),再次觸發 resolveInstanceMethod
4. 仍無實現則崩潰
unsigned int count;
objc_property_t *props = class_copyPropertyList([UIView class], &count);
for(int i = 0; i < count; i++) {
const char *name = property_getName(props[i]);
NSLog(@"%@", [NSString stringWithCString:name encoding:NSUTF8StringEncoding]);
}
free(props); // 必須釋放
可獲取 UIView 所有屬性名(如 layer, tag, backgroundColor 等)。
unsigned int count;
Method *methods = class_copyMethodList([UIView class], &count);
for(int i = 0; i < count; i++) {
SEL name = method_getName(methods[i]);
NSLog(@"%@", NSStringFromSelector(name));
}
free(methods);
相關輔助函數:method_getImplementation、method_getTypeEncoding、method_getNumberOfArguments、method_copyReturnType、method_setImplementation。
object_setClass)、方法實現 (class_replaceMethod)、通過字符串修改變量善用 Runtime 可實現熱修復、AOP 切面、自動序列化、字典轉模型等高級功能,是 iOS 進階開發必備技能。