在没有"super"的情况下调用super.关键词 [英] Call super without "super" keyword

查看:78
本文介绍了在没有"super"的情况下调用super.关键词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want' to implement "Fix and continue functionality" that was in Xcode 3.

上下文:

主要思想是: 当我需要快速修复问题"时,无需重新编译项目.我正在用'updated'方法实现编译小的Attacker class,将其加载到内存中,并替换运行时具有incorrect实现的VictimClass的方法. 我认为这种方法可以在整个项目重新编译时更快地工作.

The main idea is: When I need to "Fix something fast", I'm not re-compiling, project. I'm compiling small Attacker class with 'updated' method implementation, loading it into memory and replacing VictimClass's method which have incorrect implementation in runtime. I think that this method will work faster that full project recompilation.

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

When i'm done with fixes i'm just copying source of Attacker class method to Victim class.

问题

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

At the moment, I don't know how correctly call [super ...] in Attacker class.

例如,我有VictimClass

For example, i have 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];

此时,将调用drawRect:方法时,这将导致异常,因为drawRect:将在NSObject类而不是UIView类上被调用

At this point , when drawRect: method will be called, this will lead to exception, since drawRect: will be called on NSObject class, but not on UIView class

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

So, my question is, how correctly call [super drawRect:] in AttackerClass, to have possibility to correctly exchange implementation in runtime?

主要思想是提供一种方法,用Attacker的类方法正确替换Victim类中的任何方法.通常,您不知道Victim class的超类.

Main idea is to provide a way to correctly replace any method in Victim class by Attacker's class method. Generally, you don't know, superclass of Victim class.

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

UPDATE: Replacing implementation code added.

推荐答案

您将必须

  1. 获取接收器类(例如,使用object_getClass(rcv))
  2. 然后获取它的超类(使用class_getSuperclass(class))
  3. 然后获取其实现(使用class_getMethodImplementation(superclass, sel))
  4. 然后呼叫展示.
  1. get the receivers class (e.g. with object_getClass(rcv))
  2. then get the super class of it (with class_getSuperclass(class))
  3. then get the implementation of it (with class_getMethodImplementation(superclass, sel))
  4. then call the imp.

完成

如果您输入nil或NULL,请随时停止.

Stop at any step if you got nil or NULL.

哦,这一切似乎很愚蠢.但是我认为这个问题只是缺乏上下文,无法了解这种黑客攻击的动机.

Oh, and all this seems silly. But I assume that the question just lacks of context to see the motivation for such a hack.

[更新]

对未来读者的解释:

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

The super keyword is resolved at compile time. Therefore it does not the intended thing when changing methods at runtime. A method which is intended to be injected in some object (and its class hierarchy) at runtime has to do super calls via runtime as outlined above.

这篇关于在没有"super"的情况下调用super.关键词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆