8

需要使用类别覆盖方法。我也知道这样做的危险(这是另一个类中的私有类,没有人会编写另一个覆盖类别方法,因此不能保证未定义的行为)。我见过很多类似的问题,但它们都解决了使用以下内容抑制编译器警告的问题:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

// do your override

#pragma clang diagnostic pop

但是,这仍然会留下链接器警告。是否有可能在 Xcode 4.6 中为我认为安全的特定覆盖摆脱它?

这是一个说明问题的示例 GitHub 项目

4

1 回答 1

0

好的,正如我在评论中解释的那样,您尝试做的事情是危险的,不应该这样做。我还建议阅读运行时文档以了解原因并了解实现目标的其他方法。你应该读那个。

在任何情况下,您正在做的另一种方法是使用运行时环境“跳过”初始化层次结构中的一个类,从而有效地“覆盖”超类方法,从而产生完全相同的结果而不会引发如此多的危险信号。

这是如何完成的一个选项,在您的示例项目中,将 FunkyBranch 类实现更改为:

#import "FunkyBranch.h"
#import <objc/runtime.h>

typedef id(*InitIMP)(id,SEL);

@implementation FunkyBranch

-(id) init
{
    InitIMP superSuperInit = (InitIMP)class_getMethodImplementation([[self superclass] superclass], @selector(init));

    self = superSuperInit(self, @selector(init));
    if (self)
    {
        NSLog(@"FunkyBranch initialized");
    }
    return self;
}

@end

它将与您当前的实施具有相同的结果,而不会带来您正在做的事情的危险。

请记住,将函数指针转换为正确的类型至关重要,而且我仍然认为您应该重新考虑您的方法,而不是强迫运行时做一些它不打算做的事情。无论如何,这回答了你的问题。

于 2013-04-15T14:37:47.217 回答