Objective c Xcode-实现一个方法,也可以由它的主类实现

Objective c Xcode-实现一个方法,也可以由它的主类实现,objective-c,pragma,Objective C,Pragma,我使用的是Xcode 4.5。 在我最新的Xcode项目中,当我构建/编译程序时,会弹出以下警告: Category正在实现一个方法,该方法也将由其主类实现 这是导致错误的代码: @implementation NSApplication (SDLApplication) - (void)terminate:(id)sender { SDL_Event event; event.type = SDL_QUIT; SDL_PushEvent(&event); }

我使用的是Xcode 4.5。 在我最新的Xcode项目中,当我构建/编译程序时,会弹出以下警告:

Category正在实现一个方法,该方法也将由其主类实现

这是导致错误的代码:

 @implementation NSApplication (SDLApplication)
 - (void)terminate:(id)sender {
    SDL_Event event;
    event.type = SDL_QUIT;
    SDL_PushEvent(&event); }
 @end
我这样做是为了让编译器忽略(或跳过)使用
pragma code
生成的警告

现在我的代码如下所示:

 @implementation NSApplication (SDLApplication)

 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
 - (void)terminate:(id)sender{
   SDL_Event event;
   event.type = SDL_QUIT;
   SDL_PushEvent(&event);}
 #pragma clang diagnostic pop
 @end
显然,它完成了任务,并且一旦构建/编译,就不会生成任何警告

我的问题是,以这种方式抑制或忽略警告是否安全/正常

我在一些帖子上读到使用子类是有好处的,但是有很多人赞成和反对以这种方式使用它们。。。我很感激你的想法:)

不。 在类别中重写(或重新实现)方法,特别是关键的系统方法,如
-terminate:
,会导致未定义的行为。显然,退出应用程序不应该是一场侥幸的游戏。子类NSApplication和override
-终止:
(最后调用super),然后在info.plist中将其指定为主体类
Pragma
s不是警告修正器,它们只是抑制器

“我在一些线程上读到使用子类是有利的…”

使用子类可能是有利的,但这不是您在这里要做的

您所做的是在
NSApplication
上实现一个
(sdlaapplication)
。在该类别中,您将覆盖
NSApplication
terminate:
方法。通常,您应该仅使用类别向现有类添加其他方法,而不是覆盖现有方法,因为这可能会产生不可预测的结果

您真正应该做的是子类
NSApplication
,这样您就可以正确地覆盖
终止:

@interface SDLApplication : NSApplication {

}

@end


@implementation

- (void)terminate:(id)sender {
   SDL_Event event;
   event.type = SDL_QUIT;
   SDL_PushEvent(&event);
   [super terminate:sender]; // this line is the key to assuring proper behavior
}

@end
被重写的
terminate:
方法中的最后一步应该是调用
super
,以便terminate方法正常工作。(不允许在类别中使用关键字
super
;只有单词
self
,这就是为什么需要子类化的原因)


确保将
Info.plist
文件中的
NSPrincipalClass
键的值更改为
sdlaApplication
,而不是
NSApplication

只要方法链接到
all\u load
,那么当方法使用协议覆盖现有方法时,实际上会发生什么情况,这是一个很好的定义。这样做有很多正当的理由,主要是修改第三方的框架,而不是开源的框架来修复bug。@RichardJ.RossIII:您所描述的被称为“猴子补丁”,也称为“鸭子出击”:)请看,但我假设基于上述实现(对SDL的调用),意味着他不在那种情况下。它所需要的只是一个子类和一个额外的超级调用,而不是把他弄得晦涩难懂和未来的bug。我同意。而
pragma
代码当时只是为了抑制警告。我打算从这篇文章的答案中找到正确的解决方法。谢谢您的解释。如果您将二进制文件与
所有加载链接,那么是的,它是安全的。但是,只要有可能,您应该更喜欢其他方法,因为这是一种非常隐蔽的方法,虽然它可以工作,但对于大型项目来说,它不是非常可维护的。是的,我知道我的原始代码没有使用子类。我只是在某个地方读到,这是一种替代方法,而不仅仅是使用
pragma
s来抑制警告。话虽如此,我还不能100%确定如何在
C++
中实现子类,这确实非常有用:)感谢您花时间解释这一点。