首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C Runtime 類操作完全指南:動態獲取、修改、方法交換

     編輯:關於C語言

前置準備

#import 

// User 類別定義
@interface User : NSObject
@property (nonatomic, copy) NSString *userName;
- (id)initWithUserName:(NSString *)userName;
+ (id)userWithUserName:(NSString *)userName;
@end

一、類對象獲取與繼承關係

Class userClass = objc_getClass("User");   // 或 [User class]
Class superClass = class_getSuperclass(userClass);  // NSObject

二、修改實例的類(isa 指向)

User *user = [User new];
Class original = object_setClass(user, [AnotherClass class]);  // 替換 isa
// 原類別方法失效,新類別方法生效

三、類名轉換

const char *cName = class_getName(userClass);           // "User"
NSString *name = NSStringFromClass(userClass);          // @"User"
name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];

四、屬性枚舉與存取

unsigned int count;
objc_property_t *props = class_copyPropertyList(userClass, &count);
for (i=0; i

五、方法操作大全

1. 列舉所有實例方法

Method *methods = class_copyMethodList(userClass, &count);
for (i=0; i

2. 獲取類/實例方法

SEL sel = sel_registerName("userWithUserName:");
Method clsMethod = class_getClassMethod(userClass, sel);

sel = sel_registerName("initWithUserName:");
Method instMethod = class_getInstanceMethod(userClass, sel);

3. 獲取實作 IMP

IMP imp = method_getImplementation(instMethod);
imp = class_getMethodImplementation(userClass, sel);
imp = [user methodForSelector:sel];

4. 動態新增方法

BOOL added = class_addMethod(userClass, @selector(newMethod:), (IMP)newMethodIMP, "v@:@");
if (added && class_respondsToSelector(userClass, @selector(newMethod:))) { … }

5. 方法交換

Method m1 = class_getInstanceMethod([self class], @selector(methodA));
Method m2 = class_getInstanceMethod([self class], @selector(methodB));
method_exchangeImplementations(m1, m2);  // 交換 IMP

6. 方法替換

Method src = class_getInstanceMethod([self class], @selector(methodA));
IMP srcImp = method_getImplementation(src);
Method dst = class_getInstanceMethod([self class], @selector(methodB));
method_setImplementation(dst, srcImp);   // dst 指向 src 實作

7. 方法覆蓋

IMP oldImp = class_replaceMethod(userClass, @selector(userName), (IMP)newUserNameIMP, "i@:@");
// 僅限全局函式實作,簽名必須一致

輸出範例

獲取所有方法
方法名:initWithUserName:; 返回類型@; 參數:@24@0:8@16
方法名:userName; 返回類型@; 參數:@16@0:8
方法名:setUserName:; 返回類型v; 參數:v24@0:8@16

方法交換前後
陽君 → IOS
IOS → 陽君

注意事項

  • 所有 char* 均為 UTF-8 編碼。
  • 動態修改類結構需謹慎,影響範圍全進程。
  • ARC 環境下直接操作 Ivar 需特別小心記憶體管理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved