Xcode 9を使用しているとき、This function declaration is not a prototype
というコンパイラの警告がいくつかあります。メソッド本体にvoid
を追加することで解決できます。私が抱えている問題は、これらの警告がUIApplication
デリゲートメソッドのようなシステムAPIにも投げられることです。
- (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
今、私はデレゲートメソッドがまだ長期的に機能するのか、それともiOS 11 Beta以降のバージョンではAppleがvoid
を挿入するのかと思います。私が興味を持っているのは、void
本体を含めると、Xcodeはメソッドセレクタの不一致について文句を言うでしょう(これは意味があります)。これまでに誰かが同じ問題を経験しましたか?
空の括弧付きのブロック宣言:
void (^)()
空括弧付きの関数ポインタと同じ意味を持ちます。
void (*)()
議論がないという意味ではありません。これは、引数が指定されていないことを意味します。したがって、次の方法で呼び出すことができるので、バグへの道が開かれます。
void (^block)() = ...
block();
block(10);
block(@"myString");
パラメータなしでブロックを宣言するときは、常に次のようにしてください。
void (^)(void)
Appleはいたるところでそれを正しく行っていなかったし、互換性の理由からおそらく古いAPIのためにそれを修正していません。新しいAPIに移行するまでは、その警告をそこに残しておく必要があります。
その警告をオフにすることもできます(-Wstrict-prototypes
):
または#pragma
を使用する(Thanks @ 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が本来あるべきほど良くないことを知るだけです。