Avviso "Questa dichiarazione di funzione non è un prototipo" in Xcode 9


119

Quando si utilizza Xcode 9, ci sono alcuni avvisi del compilatore che dicono This function declaration is not a prototype. Suggerisce di aggiungere voidal corpo del metodo, che lo risolverà. Il problema che sto riscontrando è che questi avvisi vengono generati anche per i UIApplicationmetodi delegati simili alle API di sistema :

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

Questo potrebbe essere risolto come segue:

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

Ora mi chiedo se i metodi delegati funzioneranno ancora a lungo termine o Apple inserirà le voidversioni successive di iOS 11 Beta. Sono curioso perché se includo il voidcorpo, Xcode si lamenterà dei selettori di metodo non corrispondenti (il che ha senso). Qualcuno ha riscontrato lo stesso problema finora?

Risposte:


251

La dichiarazione di blocco con parentesi vuote:

void (^)()

ha la stessa semantica di un puntatore a funzione con parentesi vuote:

void (*)()

Non significa che non ci siano argomenti. Significa che gli argomenti non sono specificati, quindi apre la strada a bug poiché puoi chiamarlo nei seguenti modi:

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

Quando si dichiarano blocchi senza parametri, utilizzare sempre:

void (^)(void)

Apple non lo stava facendo correttamente ovunque e probabilmente non lo sta risolvendo per le vecchie API per motivi di compatibilità. Dovrai mantenere quell'avviso lì fino a quando non passerai alla nuova API.

Puoi anche disattivare l'avviso ( -Wstrict-prototypes): inserisci qui la descrizione dell'immagine

o usando #pragma(grazie @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

Vedi la discussione LLVM qui o il bug su openradar .

Nota che non è stata apportata alcuna modifica al funzionamento interno delle API, tutto il codice continuerà a funzionare. Sapremo solo che l'API non è buona come dovrebbe essere.


5
Puoi anche utilizzare pragmas per rimuovere l'avviso durante l'implementazione dell'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 completamentoHandler: (void (^) ()) completamentoHandler {#pragma clang diagnostic pop
davidisdk

1
Ho ricevuto circa 20 avvisi di questi con l'API JBChartView. È bello poterli disattivare finché non decidono di aggiornare per Swift 4.
Edison

7
@tymac Questo è un avviso objc. Non ha niente a che fare con Swift.
Sulthan

> "Quando dichiari blocchi senza parametri, usa sempre (void)" <Puoi aggiungere come dovrebbe apparire nel codice? In alternativa a void (^)()orvoid (*)()
pkamb

2
@pkamb Quando il blocco non prende alcun parametro (ad esempio void(^)()), includere esplicitamente voidtra parentesi: void(^)(void).
Ben Stock
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.