これを行う別の方法は、動的サブクラスを使用することです。
- (void)addCustomMethodToObject:(id)object {
Class objectClass = object_getClass(object);
SEL selectorToOverride = ...; // this is the method name you want to override
NSString *newClassName = [NSString stringWithFormat:@"Custom_%@", NSStringFromClass(objectClass)];
Class c = NSClassFromString(newClassName);
if (c == nil) {
// this class doesn't exist; create it
// allocate a new class
c = objc_allocateClassPair(objectClass, [newClassName UTF8String], 0);
// get the info on the method we're going to override
Method m = class_getInstanceMethod(objectClass, selectorToOverride);
// add the method to the new class
class_addMethod(c, selectorToOverride, (IMP)myCustomFunction, method_getTypeEncoding(m));
// register the new class with the runtime
objc_registerClassPair(c);
}
// change the class of the object
object_setClass(object, c);
}
id myCustomFunction(id self, SEL _cmd, [other params...]) {
// this is the body of the instance-specific method
// you may call super to invoke the original implementation
}
これを行った後object
、オーバーライドされたメソッドのみが受信されます。これは、特別なクラスのインスタンスである唯一のものになるためです。また、このコードはインスタンス メソッドのみをオーバーライドしますが、クラス メソッドをオーバーライドするように変更することは難しくありません。
いつものように、通常の警告:
- 警告実装者: このコードはブラウザで入力されました
- 警告オブザーバー: このコードは、キー値の監視ではうまく機能しません
- 注意 Threader : このコードはあまりスレッドセーフに見えません
- 注意 ARC'er :
objc_allocateClassPair()
ARC でコンパイルすることはできません。
- 警告 開発者: オブジェクトのクラスをいじるのは危険なことです。この種のブードゥー教には完全に正当な用途がありますが、非常にまれです。これを行う必要があると思う場合は、おそらく間違っているので、ここに新しい質問を投稿して、「これは私がしなければならないと思うことですよね?」と言ってください。