Подтвердить что ты не робот

"Объявление этой функции не является прототипом предупреждения в Xcode 9

При использовании Xcode 9, есть некоторые предупреждения компилятора о том, что This function declaration is not a prototype. Он предлагает добавить void в тело метода, что разрешит его. Проблема, с которой я столкнулся, заключается в том, что эти предупреждения также UIApplication для системного 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 тело, Xcode будет жаловаться на несоответствие селекторов метода (что имеет смысл). Кто-то испытывал ту же проблему до сих пор?

4b9b3361

Ответ 1

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

void (^)()

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

void (*)()

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

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

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

void (^)(void)

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