不使用"超级"关键字调用超级

tt.*_*lew 3 iphone objective-c objective-c-runtime ios

我想要实现Xcode 3中的"修复和继续功能".

背景:

主要思想是:当我需要"快速修复某些东西"时,我不会重新编译,投射.我正在Attacker class使用'updated'方法实现编译小,将其加载到内存中并替换incorrect在运行时实现的VictimClass方法.我认为这个方法可以更快地完成整个项目的重新编译.

当我完成修复时,我只是将Attacker class方法的来源复制到Victim class.

问题

目前,我不知道如何[super ...]在Attacker类中正确调用.

例如,我有VictimClass

@interface VictimClass : UIView @end
@implementation VictimClass
- (void)drawRect:(CGRect)rect {
  [super drawRect:rect];
}
@end


@interface AttackerClass : NSObject @end
@implementation AttackerClass 
- (void)drawRect:(CGRect)rect {
  [super drawRect:rect];
  [self setupPrettyBackground];
}
@end
....

// EXCHANGE IMPLEMENTATIONS
Method m = class_getInstanceMethod([AttackerClass class], @selector(drawRect:));
const char * types = method_getTypeEncoding(m);
IMP attackerImp = method_getImplementation(m);

class_replaceMethod([VictimClass class], @selector(drawRect:), attackerImp, types);


// Invoking drawRect on Victim
VictimClass * view = /* */;
[view setNeedsDisplay];
Run Code Online (Sandbox Code Playgroud)

此时,当drawRect:调用方法时,这将导致异常,因为drawRect:将在NSObject类上调用,但不会在UIView类上调用

所以,我的问题是,如何正确调用[super drawRect:]AttackerClass,有可能在运行时正确交换实现?

主要思想是提供一种方法,通过Attacker的类方法正确替换Victim类中的任何方法.一般来说,你不知道,超类Victim class.

更新:替换添加的实现代码.

Til*_*ütz 5

你不得不

  1. 得到接收器类(例如object_getClass(rcv))
  2. 然后得到它的超类(带class_getSuperclass(class))
  3. 然后得到它的实现(与class_getMethodImplementation(superclass, sel))
  4. 然后打电话给imp.

DONE

如果你有nil或NULL,则在任何步骤停止.

哦,这一切看起来很傻.但我认为这个问题只是缺乏上下文来看待这种黑客的动机.

[更新]

对未来读者的解释:

super关键字在编译时得到解决.因此,在运行时更改方法时,它不是预期的事情.在运行时打算注入某个对象(及其类层次结构)的方法必须通过运行时进行超级调用,如上所述.