Xcode 9中的“此函数声明不是原型”警告


119

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

这可以通过以下方法解决:

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

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

Answers:


251

带空括号的块声明:

void (^)()

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

void (*)()

这并不意味着没有论点。这意味着未指定参数,因此可以打开bug的途径,因为您可以通过以下方式进行调用:

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

声明不带参数的块时,请始终使用:

void (^)(void)

苹果公司并没有在所有地方正确地做到这一点,并且出于兼容性原因,他们可能没有针对旧API进行修复。您必须将警告保留在那里,直到您使用较新的API。

您也可以关闭该警告(-Wstrict-prototypes): 在此处输入图片说明

或使用#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上的错误。

请注意,API的内部工作没有任何变化,所有代码仍将工作。我们只会知道API不够理想。


5
在实现iOS API时,您还可以使用编译指示来消除警告:#pragma clang诊断推送#pragma clang诊断忽略“ -Wstrict-prototypes”-(void)应用程序:(UIApplication *)应用程序handleActionWithIdentifier:(NSString *)RemoteNotification的标识符: (NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfocompletedHandler:(void(^)())completionHandler {#pragma clang diagnostic pop
davidisdk

1
使用JBChartView API可以得到20条警告。很高兴能够将其关闭,直到他们决定更新斯威夫特4
爱迪生

7
@tymac这是一个objc警告。它与Swift无关。
苏珊(Sulthan),

>“当声明不带参数的块时,请始终使用(void)” <您可以添加代码中的外观吗?作为void (^)()或的替代方案void (*)()
pkamb

2
@pkamb当您的代码块不带任何参数(即void(^)())时,显式包含void在括号中:void(^)(void)
本·
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.