Objective c 重写类别中的类实例方法时,如何抑制链接器警告

Objective c 重写类别中的类实例方法时,如何抑制链接器警告,objective-c,clang,Objective C,Clang,我需要使用类别重写一个方法。我也意识到这样做的危险性(这是另一个类中的私有类,没有人会编写另一个重写category方法,因此不能保证有未定义的行为)。我见过很多类似的例子,但它们都使用以下内容来解决抑制编译器警告的问题: #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" // do your override #pragma clang

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

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

// do your override

#pragma clang diagnostic pop
但是,这仍然会留下链接器警告。在Xcode 4.6中,我认为安全的特殊覆盖是否可以去掉它


这里有一个例子来说明这个问题。

好的,正如我在评论中解释的,你试图做的是危险的,不应该做。我还建议你阅读这篇文章,了解原因,并了解实现目标的其他方法。你应该读一下

在任何情况下,一种替代方法是使用运行时环境“跳过”初始化层次结构中的一个类,从而有效地“重写”超类方法,这种方法可以产生完全相同的结果,而不会引起太多的危险

这里有一个方法选项,在您的示例项目中,将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
#导入“FunkyBranch.h”
#进口
类型定义id(*InitIMP)(id,SEL);
@执行处
-(id)init
{
InitIMP superSuperInit=(InitIMP)类_getMethodImplementation([[self superclass]superclass],@selector(init));
self=superSuperInit(self,@selector(init));
如果(自我)
{
NSLog(@“FunkyBranch已初始化”);
}
回归自我;
}
@结束
它将产生与您当前的实现相同的结果,而不存在您正在做的事情的危险


请记住,将函数指针转换为正确的类型是最重要的,而且我仍然认为您应该重新考虑您的方法,而不是强制运行时执行它不打算执行的操作。无论如何,这回答了您的问题。

如果您愿意解释为什么需要它,我们可能会为您提供其他解决方案。您的示例代码没有告诉我们为什么不使用子类化的原因,因为在本例中并不明显。@vikingosegundo我想替换一个方法实现,同时仍然保留对其超类的访问权(并且发现这是一种比方法swizzling更优雅的方法)。有关更多信息,请参见此问题:在该问题中,我要求提供该问题的其他解决方案。在这里,我只是问如何抑制实际链接警告,以供将来参考。我从来不会考虑抑制警告是优雅的。也许它没有方法swizzling那么丑陋……为什么您认为在您的案例中没有未定义的行为是可以保证的?From:在Apple文档中:“如果类别中声明的方法的名称与原始类中的方法相同,…,则在运行时使用的方法实现的行为未定义。”您可以尝试方法swizzleFWIW,这是一种相当合理的方法(OP)来覆盖方法,例如用于测试的方法。我们通过这种方式重写方法来控制它们的实现,只使用为测试目标加载的类别。这并没有那么可怕,依我看。这是一个巧妙的把戏,虽然有点模糊。