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

当使用 Xcode 9时,有一些编译器警告说 This function declaration is not a prototype。它建议将 void添加到方法体中,这将解析它。我遇到的问题是,这些警告也会抛出到 system-API 类似于 UIApplication委托-方法中:

- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)userInfo
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void (^)())completionHandler

这个问题可以通过以下方式解决:

- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)userInfo
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void (^)(void))completionHandler

现在我想知道委托方法是否仍然可以长期使用,或者苹果将在 iOS11Beta 版本中插入 void。我很好奇,因为如果我包含 void主体,Xcode 会抱怨方法选择器不匹配(这是有意义的)。到目前为止有人遇到过同样的问题吗?

48109 次浏览

带空括号的块声明:

void (^)()

与带空括号的函数指针具有相同的语义:

void (*)()

这并不意味着没有争论。这意味着没有指定参数,因此它打开了 bug 的通道,因为您可以通过以下方式调用它:

void (^block)() = ...
block();
block(10);
block(@"myString");

当声明没有参数的块时,始终使用:

void (^)(void)

苹果并没有在所有地方都正确地做到这一点,而且他们可能也没有出于兼容性的原因对旧的 API 进行修复。在转移到新的 API 之前,必须保留这个警告。

您还可以关闭该警告(-Wstrict-prototypes) : enter image description here

或使用 #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

请参阅 LLVM 讨论 给你openradar上的 bug。

注意,API 的内部工作没有变化,所有代码仍然可以工作。我们只知道 API 没有达到应有的水平。