Предупреждение" это объявление функции не является прототипом " в 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

теперь мне интересно, будут ли методы делегата по-прежнему работать в долгосрочной перспективе или Apple вставит void в более поздних бета-версиях iOS 11. Мне любопытно, потому что если я включу void body, Xcode будет жаловаться на несоответствие метод-селекторов (что имеет смысл). Кто-то испытывал ту же проблему до сих пор?

1 ответов


объявление блока с пустой скобкой:

void (^)()

имеет ту же семантику, что и указатель функции с пустой скобкой:

void (*)()

это не значит, что нет аргументов. Это означает, что аргументы не заданы, поэтому он открывает путь к ошибкам, так как вы можете вызвать ее следующим образом:

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

при объявлении блоков без параметров всегда используйте:

void (^)(void)

Apple делала это неправильно везде, и они, вероятно, не фиксируют это для старых 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.

обратите внимание, что никаких изменений в внутренняя работа API, весь код будет по-прежнему работать. Мы будем знать только, что API не так хорош, как должен быть.