次の方法を検討してください
- (void)methodWithArg:(NSString *)arg1 andArg:(NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
新しいnonnull
およびnullable
注釈キーワード を使用すると、次のように強化できます。
- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
ただし、次の警告も表示されます。
ポインターにnullability型指定子がありません(__nonnullまたは__nullable)
3番目のパラメーター(ブロック1)を参照します。
documentation では、ブロックパラメーターのNULL可能性を指定する方法の例は説明していません。逐語的
型が単純なオブジェクトまたはブロックポインターである限り、開きかっこの直後に、下線のないフォームをnull可能およびnull以外を使用できます。
ブロックの2つのキーワードの1つを(任意の位置に)運を出さずに置いてみました。アンダースコアの接頭辞付きバリアント(__nonnull
および__nullable
)も試してみました。
したがって、私の質問は次のとおりです。ブロックパラメーターにnullabilityセマンティクスを指定するにはどうすればよいですか。
これは機能しているようです
- (void)methodWithArg:(nonnull NSString *)arg1
andArg:(nullable NSString *)arg2 completionHandler:(nullable void (^)
(NSArray * _Nullable results, NSError * _Nonnull error))completionHandler
ブロックとそのパラメーターの両方にnullabilityを指定する必要があります...
編集:詳細については、 Swift Blog を参照してください
Apple Blog( "Nullability and Objective-C") によると、使用できます
NS_ASSUME_NONNULL_BEGIN
およびNS_ASSUME_NONNULL_END
。
これらの領域内では、単純なポインタータイプはすべてnonnull
と見なされます。次に、nullを許可するオブジェクトにnullable
を追加します。
NS_ASSUME_NONNULL_BEGIN
@interface MyClass: NSObject
- (void)methodWithArg:(NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
@end
NS_ASSUME_NONNULL_END
NSError **
タイプの場合、NSError * _Nullable * _Nullable
である必要がありますid *
型の場合、id _Nullable * _Nonnull
を使用する方が適切です。これは依存します(_Nullable id * _Nullable
型が必要な場合があります)。NSObject *
型の場合、このNSObject * _Nullable * _Nonnull
のように、ポインターの後に注釈を付ける必要があります注
_Nonnull
および_Nullable
は、ポインターまたはid
の後に使用する必要があります(AppleはサンプルコードAAPLListItem * _Nullable
で使用します)が、下線のない形式nonnull
およびnullable
は、括弧の後に使用できます。
ただし、一般的なケースでは、これらの注釈を記述するより良い方法があります。メソッド宣言内では、型が単純なオブジェクトまたはブロックポインターである限り、アンダースコアなしのフォーム
nullable
およびnonnull
をすぐに使用できます。
"Nullability and Objective-C" で詳細を確認してください
安全のため、この規則にはいくつかの例外があります。
typedef
型には通常、固有のNULL可能性はありません。これらは、コンテキストに応じて、容易にNULL可能またはNULL不可にすることができます。したがって、監査された領域内であっても、typedef
型はnonnull
と見なされません。id *
などのより複雑なポインター型には、明示的に注釈を付ける必要があります。たとえば、null許容オブジェクト参照への非null可能ポインターを指定するには、_Nullable id * _Nonnull
を使用します。- 特定のタイプ
NSError **
は、メソッドパラメーターを介してエラーを返すために頻繁に使用されるため、常にNULL可能NSError
参照へのNULL可能ポインターと見なされます。
_Nullable id * _Nonnull
は混乱する可能性があり、id _Nullable * _Nonnull
の方が理解しやすいです。
_Nonnull
および_Nullable
は、ポインターまたはid
の後に使用する必要があります(APPLEはコード例AAPLListItem * _Nullable
で使用します)
次のようにすることもできます。
- (id __nullable)methodWithArg:(NSString * __nullable)arg1
andArg:(NSString * __nonnull)arg2
completionHandler:(void (^ __nonnull)(NSArray * __nonnull results, NSError * __nullable error))completionHandler;
それはあなたがより好きな構文に依存します。
ヘッダーファイルで補完を定義するには、これを行いました
typedef void (^PublicEventsHandler) (BOOL success, NSArray * _Nullable publicEvents);
もちろん、受け入れられた答えに同意します。
Appleから 開発者ブログ :コア:_Nullableおよび_Nonnull
型が単純なオブジェクトまたはブロックポインターである限り、下線のないフォームはnull可能およびnull以外を開きかっこの直後に使用できます。
下線のないフォームは下線のあるフォームよりも優れていますが、ヘッダーのすべてのタイプに適用する必要があります。