我需要使用类别覆盖方法。我也意识到这样做的危险(这是另一个类中的私有类,没有人会编写另一个重写类别方法,所以没有保证未定义的行为)。我已经看到很多类似的questions,但它们都解决了使用类似这样的事情来抑制编译器警告:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
// do your override
#pragma clang diagnostic pop
然而,这仍然会留下链接器警告。在Xcode 4.6中,是否有可能摆脱我认为安全的特定覆盖?
这是一个说明问题的sample GitHub project。
答案 0 :(得分:0)
好的,正如我在评论中解释的那样,你要做的事情是危险的,不应该这样做。我还建议阅读runtime documentation以了解原因,并了解实现目标的其他方法。你应该读一下。
在任何情况下,替代你正在做的事情,产生完全相同的结果而不引起这么多的红旗,是使用运行时环境“跳过”初始化层次结构中的一个类,有效地“覆盖”超类方法
以下是一个如何完成的选项,在您的示例项目中,将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
它将与您当前的实现具有相同的结果,而不会有您正在做的事情的危险。
请记住,将函数指针强制转换为正确的类型是至关重要的,我仍然认为你应该重新考虑你的方法,而不是强迫运行时做一些它不打算做的事情。无论如何,这都回答了你的问题。