Objective c Xcode-实现一个方法,也可以由它的主类实现
我使用的是Xcode 4.5。 在我最新的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); }
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++
中实现子类,这确实非常有用:)感谢您花时间解释这一点。