ios Xcode 9 中的“此函数声明不是原型”警告
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44473146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"This function declaration is not a prototype" warning in Xcode 9
提问by Hans Kn?chel
When using Xcode 9, there are some compiler warnings saying This function declaration is not a prototype
. It suggests to add void
to the method body, which will resolve it. The issue I am having is that those warnings are also thrown for system-API's like UIApplication
delegate-methods:
使用 Xcode 9 时,有一些编译器警告说This function declaration is not a prototype
. 它建议添加void
到方法体,这将解决它。我遇到的问题是,系统 API 也会抛出这些警告,例如UIApplication
委托方法:
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)userInfo
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void (^)())completionHandler
This could be resolved by the following:
这可以通过以下方式解决:
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)userInfo
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void (^)(void))completionHandler
Now I am wondering if the delegate methods will still work on the long-term or Apple will insert the void
in later iOS 11 Beta versions. I am curious because if I include the void
body, Xcode will complain about mismatching method-selectors (which makes sense). Did someone experience the same issue so far?
现在我想知道委托方法是否仍然可以长期工作,或者 Apple 会void
在以后的 iOS 11 Beta 版本中插入。我很好奇,因为如果我包含void
正文,Xcode 会抱怨方法选择器不匹配(这是有道理的)。到目前为止有人遇到过同样的问题吗?
回答by Sulthan
The block declaration with empty parenthesis:
带空括号的块声明:
void (^)()
has the same semantics as a function pointer with empty parenthesis:
与带空括号的函数指针具有相同的语义:
void (*)()
It does not mean that there are no arguments. It means the arguments are not specified, therefore it opens the way to bugs since you can call it in the following ways:
这并不意味着没有争论。这意味着未指定参数,因此它为错误开辟了道路,因为您可以通过以下方式调用它:
void (^block)() = ...
block();
block(10);
block(@"myString");
When declaring blocks with no parameters, always use:
声明不带参数的块时,请始终使用:
void (^)(void)
Apple was not doing that correctly everywhere and they are not probably fixing that for old APIs for compatibility reasons. You will have to keep that warning there until you move to the newer API.
Apple 并没有在任何地方正确地做到这一点,并且出于兼容性原因,他们可能不会为旧 API 修复该问题。您必须在那里保留该警告,直到您转向较新的 API。
You can also turn off that warning (-Wstrict-prototypes
):
您还可以关闭该警告 ( -Wstrict-prototypes
):
or using #pragma
(thanks @davidisdk):
或使用#pragma
(感谢@davidisdk):
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-prototypes"
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)userInfo
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void (^)())completionHandler {
}
#pragma clang diagnostic pop
See the LLVM discussion hereor the bug on openradar.
Note that's there was no change in the internal working of the APIs, all code will still work. We will only know that the API is not as good as it should be.
请注意,API 的内部工作没有变化,所有代码仍然可以工作。我们只会知道 API 没有应有的好。