覆盖单个对象实例中的方法

时间:2011-06-02 11:51:36

标签: objective-c override

我不知道怎么说这个,我找不到答案,因为我无法找到表达所需内容的词语。 (!)

在Java中,我曾经做过类似的事情(我不记得了):

JPanel myButton = new JPanel("Press me"){
    public void add(JComponent component){
        //override add method
    }
};

但是,我在Objective-C中找不到如何做到这一点。我在搜索中发现的是类别和奇怪的^ {}符号......

那么,我如何覆盖新创建的对象中的方法?

(例如,在新创建的-(BOOL)isEqual;中覆盖NSString*?)

很抱歉,如果这个问题有点模糊......

编辑:

显然,没有子类化:)

编辑:

如果有人有更好的想法,也可以发布我的问题:

我在COCOS2D中有一些CCTransition,我希望在转换结束时收到通知。事情是,一旦转换结束, - (void)完成;调用方法(这是CCTransition类结构的一部分)

我真的想避免继承CCTransition类,并在转换结束时覆盖finish方法来执行我的逻辑:)

编辑:

- (void)onEnterTransitionDidFinish; ......我无法相信那些存在的东西,并且在搜索时我没有遇到过它......

这意味着,不是子类化CCTransition,而是在我的CCNode子类中重写此方法:D!

3 个答案:

答案 0 :(得分:6)

它仍然不会很干净,但假设你愿意集中丑陋,你可以做一些像(未经测试的):

Method methodToReplace =
          [targetClass instanceMethodSignatureForSelector:@selector(methodToReplace)];
IMP implementationToSet =
          [someProxyClass instanceMethodForSelector:@selector(implementationYouWant)];

method_setImplementation(methodToReplace, implementationToSet);

相关参考文档是Objective-C Runtime Reference,也可以是NSObject Class Reference(因为它会使一些事情略微整洁,但是例如你可以从运行时使用class_getInstanceMethod而不是{{} 1}})。

请注意,如果您完全使用该配方,则无法调用原始实现。 method_setImplementation返回旧的实现,通常明智的做法是将它添加到全新选择器下的类中并调用它。

作为参考,我有一个合理的理由只做一次这样的事情:当我们在iOS应用程序中实现打印支持时,需要与OS 3.2和4.0兼容。您需要子类化特定的类,但该类在3.2中不可用。因此,您必须在运行时进行子类化(尽管概念上更简洁的方法是使用普通子类,将其放入框架和弱链接,但Apple的iOS SDK术语仅允许静态库,所以......)。

答案 1 :(得分:3)

根据Daniel的建议,您可以在表单的NSObject类别中实现方法

[anObject overrideMethod:@selector(foo:) 
          byBlock:^(id self,id super,id originalArg){
          ...
}];

您需要做的是

  1. objc_allocateClassPair针对self自己的类,创建一个新的临时类
  2. 使用例如,将块转换为函数指针。 thisthis
  3. method_setImplementation将新实现设置为临时类
  4. 使用object_setClassself将类设置为新的临时类
  5. 我还没想出如何向块提供super:p
  6. 据信这基本上是Apple如何完成KVO,例如this discussion.

    阅读Runtime reference

答案 2 :(得分:2)

你在Java中拥有的是一个匿名子类。这在Objective-C中是不可能的(好吧,它有点但你必须对Obj-C运行时库进行一些非常复杂的扭曲)。

但iOS 4或OS X 10.6中的Objective-C具有“块”,这是^{}语法的用途。这是Objective-C的closure概念。如果您调用的API不支持块回调,则无法直接帮助您,但您可以创建使用块而不是子类方法来处理回调的包装类。

在Objective-C中学习块有many resources