122 votes

Avertissement "This function declaration is not a prototype" dans Xcode 9

Lorsque vous utilisez Xcode 9, il y a des avertissements du compilateur qui disent que This function declaration is not a prototype . Il suggère d'ajouter void au corps de la méthode, qui le résoudra. Le problème que je rencontre est que ces avertissements sont également émis pour les API système telles que UIApplication les méthodes de délégation :

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

Ce problème pourrait être résolu de la manière suivante :

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

Je me demande maintenant si les méthodes de délégation fonctionneront toujours sur le long terme ou si Apple insérera la méthode de la void dans les versions bêta ultérieures d'iOS 11. Je suis curieux car si j'inclus le void Xcode se plaindra que les sélecteurs de méthodes ne correspondent pas (ce qui est logique). Quelqu'un a-t-il rencontré le même problème jusqu'à présent ?

257voto

Sulthan Points 23360

La déclaration du bloc avec des parenthèses vides :

void (^)()

a la même sémantique qu'un pointeur de fonction avec des parenthèses vides :

void (*)()

Cela ne signifie pas qu'il n'y a pas d'arguments. Cela signifie que les arguments ne sont pas spécifiés, ce qui ouvre la voie à des bogues puisque vous pouvez l'appeler de la manière suivante :

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

Lorsque vous déclarez des blocs sans paramètres, utilisez toujours :

void (^)(void)

Apple ne le faisait pas correctement partout et ils ne le font probablement pas pour les anciennes API pour des raisons de compatibilité. Vous devrez conserver cet avertissement jusqu'à ce que vous passiez à une API plus récente.

Vous pouvez également désactiver cet avertissement ( -Wstrict-prototypes ) : enter image description here

ou en utilisant #pragma (merci @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

Voir la discussion sur LLVM aquí ou le bug sur openradar .

Notez qu'il n'y a pas eu de changement dans le fonctionnement interne des APIs, tout le code fonctionnera toujours. Nous saurons seulement que l'API n'est pas aussi bonne qu'elle devrait l'être.

5 votes

Vous pouvez également utiliser des pragmas pour supprimer l'avertissement lors de la mise en œuvre de l'API iOS : #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

1 votes

J'en ai eu une vingtaine d'avertissements avec l'API JBChartView. C'est bien de pouvoir les désactiver jusqu'à ce qu'ils décident de faire une mise à jour pour Swift 4.

7 votes

@tymac C'est un avertissement d'objc. Il n'a rien à voir avec Swift.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X