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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:13:20  来源:igfitidea点击:

"This function declaration is not a prototype" warning in Xcode 9

iosobjective-cxcodeios11xcode9-beta

提问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 voidto the method body, which will resolve it. The issue I am having is that those warnings are also thrown for system-API's like UIApplicationdelegate-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 voidin later iOS 11 Beta versions. I am curious because if I include the voidbody, 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): enter image description here

您还可以关闭该警告 ( -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.

请参阅此处的 LLVM 讨论或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 没有应有的好。