Xcode 9'da "Bu işlev bildirimi bir prototip değildir" uyarısı


119

Xcode 9 kullanırken, derleyici bazı uyarılar vardır This function declaration is not a prototype. Onu voidçözecek olan yöntem gövdesine eklemeyi önerir . Karşılaştığım sorun, bu uyarıların sistem API'leri gibi UIApplicationtemsilci yöntemleri için de atılması :

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

Bu, aşağıdakilerle çözülebilir:

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

Şimdi, temsilci yöntemlerinin uzun vadede hala çalışıp çalışmayacağını veya Apple'ın voiddaha sonraki iOS 11 Beta sürümlerine ekleyip eklemeyeceğini merak ediyorum . Merak ediyorum, çünkü eğer voidgövdeyi dahil edersem , Xcode yöntem seçicilerinin uyumsuzluğundan şikayet edecek (bu mantıklı). Birisi şimdiye kadar aynı sorunu yaşadı mı?

Yanıtlar:


251

Boş parantezli blok bildirimi:

void (^)()

boş parantezli bir işlev göstericisiyle aynı anlam bilgisine sahiptir:

void (*)()

Tartışma olmadığı anlamına gelmez. Bu, argümanların belirtilmediği anlamına gelir, bu nedenle, aşağıdaki şekillerde arayabileceğiniz için hatalara yol açar:

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

Parametresiz blokları bildirirken her zaman şunu kullanın:

void (^)(void)

Apple bunu her yerde doğru bir şekilde yapmıyordu ve muhtemelen eski API'ler için uyumluluk nedenleriyle bunu düzeltmiyorlar. Yeni API'ye geçene kadar bu uyarıyı orada tutmanız gerekecek.

Ayrıca bu uyarıyı kapatabilirsiniz ( -Wstrict-prototypes): görüntü açıklamasını buraya girin

veya kullanarak #pragma(teşekkürler @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 tartışmasına buradan veya openradar'daki hataya bakın .

API'lerin dahili çalışmasında herhangi bir değişiklik olmadığını, tüm kodun çalışmaya devam edeceğini unutmayın. Yalnızca API'nin olması gerektiği kadar iyi olmadığını bileceğiz.


5
Ayrıca, iOS API'yi uygularken uyarıyı kaldırmak için pragmaları da kullanabilirsiniz: #pragma clang diagnostik push #pragma clang diagnostiği yok sayılır "-Wstrict-prototypes" - (void) uygulama: (UIApplication *) application handleActionWithIdentifier: (NSString *) tanımlayıcı içinRemoteNotification: (NSDictionary *) UserInfo withResponseInfo: (NSDictionary *) responseInfo completeHandler: (void (^) ())
completeHandler

1
JBChartView API ile bunlarla ilgili yaklaşık 20 uyarı aldım. Swift 4 için güncelleme yapmaya karar verene kadar onları kapatabilmek güzel.
Edison

7
@tymac Bu bir objc uyarısıdır. Swift ile ilgisi yok.
Sulthan

> "Parametre içermeyen blokları bildirirken, her zaman (void) kullanın" <Kodda nasıl görünmesi gerektiğini ekleyebilir misiniz? Alternatif olarak void (^)()ya davoid (*)()
pkamb

2
senin blok herhangi bir parametreyi (yani almaz zaman @pkamb void(^)()), özellikle dahil voidparantez içinde: void(^)(void).
Ben Stock
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.