如何在基于块的 API 方法中使用非空和可为空的 Objective-C 关键字
How to use nonnull and nullable Objective-C keywords in block-based API method
考虑以下方法
- (void)methodWithArg:(NSString *)arg1 andArg:(NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
有了新的 nonnull
和 nullable
annotation keywords 我们可以如下丰富它:
- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
但我们也收到此警告:
Pointer is missing a nullability type specifier (__nonnull or
__nullable)
指的是第三个参数(块一)
documentation 没有举例说明如何指定块参数的可空性。它逐字说明
You can use the non-underscored forms nullable and nonnull immediately
after an open parenthesis, as long as the type is a simple object or
block pointer.
我尝试为块(在任何位置)放置两个关键字之一,但没有成功。还尝试了下划线前缀变体(__nonnull
和 __nullable
)。
因此我的问题是:如何为块参数指定可空性语义?
这似乎有效
- (void)methodWithArg:(nonnull NSString *)arg1
andArg:(nullable NSString *)arg2 completionHandler:(nullable void (^)
(NSArray * _Nullable results, NSError * _Nonnull error))completionHandler
您需要为块及其参数指定可空性...
编辑:有关详细信息,请参阅 Swift Blog
这是我在 NSError ** 案例中使用的内容:
-(BOOL) something:(int)number withError:(NSError *__autoreleasing __nullable * __nullable)error;
为了在头文件中定义补全,我这样做了
typedef void (^PublicEventsHandler) (BOOL success, NSArray * _Nullable publicEvents);
当然,我同意接受的答案。
来自 apple developer blog:核心:_Nullable 和 _Nonnull
you can use the non-underscored forms
nullable and nonnull immediately after an open parenthesis, as long as
the type is a simple object or block pointer.
The non-underscored forms are nicer than the underscored ones, but
you’d still need to apply them to every type in your header.
你也可以这样做:
- (id __nullable)methodWithArg:(NSString * __nullable)arg1
andArg:(NSString * __nonnull)arg2
completionHandler:(void (^ __nonnull)(NSArray * __nonnull results, NSError * __nullable error))completionHandler;
只看你更喜欢哪种语法。
根据Apple Blog ("Nullability and Objective-C"),
你可以使用
NS_ASSUME_NONNULL_BEGIN
和 NS_ASSUME_NONNULL_END
.
在这些区域内,任何简单的指针类型都将被假定为 nonnull
。然后你可以为可为空的对象添加 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
- 如果error是
NSError **
类型,应该是NSError * _Nullable * _Nullable
- 如果对象是
id *
类型,最好使用 id _Nullable * _Nonnull
,这取决于(可能你想要 _Nullable id * _Nullable
类型)。
- 如果对象是
NSObject *
类型,需要在指针后面加上注解,像这样NSObject * _Nullable * _Nonnull
备注
_Nonnull
和 _Nullable
应在指针或 id
之后使用(Apple 在示例代码 AAPLListItem * _Nullable
中这样做),但非下划线形式 nonnull
和 nullable
可以在左括号后使用。
However, in the common case there’s a much nicer way to write these
annotations: within method declarations you can use the
non-underscored forms nullable
and nonnull
immediately after an open
parenthesis, as long as the type is a simple object or block pointer.
在"Nullability and Objective-C"
中查看更多内容
For safety, there are a few exceptions to this rule:
typedef
types don’t usually have an inherent nullability—they can
easily be either nullable or non-nullable depending on the context.
Therefore, typedef
types are not assumed to be nonnull
, even within
audited regions.
- More complex pointer types like
id *
must be
explicitly annotated. For example, to specify a non-nullable pointer
to a nullable object reference, use _Nullable id * _Nonnull
.
- The particular type
NSError **
is so often used to return errors via
method parameters that it is always assumed to be a nullable pointer
to a nullable NSError
reference.
_Nullable id * _Nonnull
容易混淆,id _Nullable * _Nonnull
更好理解。
_Nonnull
和 _Nullable
应在指针或 id
之后使用(Apple 在示例代码中使用 AAPLListItem * _Nullable
)
考虑以下方法
- (void)methodWithArg:(NSString *)arg1 andArg:(NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
有了新的 nonnull
和 nullable
annotation keywords 我们可以如下丰富它:
- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
但我们也收到此警告:
Pointer is missing a nullability type specifier (__nonnull or __nullable)
指的是第三个参数(块一)
documentation 没有举例说明如何指定块参数的可空性。它逐字说明
You can use the non-underscored forms nullable and nonnull immediately after an open parenthesis, as long as the type is a simple object or block pointer.
我尝试为块(在任何位置)放置两个关键字之一,但没有成功。还尝试了下划线前缀变体(__nonnull
和 __nullable
)。
因此我的问题是:如何为块参数指定可空性语义?
这似乎有效
- (void)methodWithArg:(nonnull NSString *)arg1
andArg:(nullable NSString *)arg2 completionHandler:(nullable void (^)
(NSArray * _Nullable results, NSError * _Nonnull error))completionHandler
您需要为块及其参数指定可空性...
编辑:有关详细信息,请参阅 Swift Blog
这是我在 NSError ** 案例中使用的内容:
-(BOOL) something:(int)number withError:(NSError *__autoreleasing __nullable * __nullable)error;
为了在头文件中定义补全,我这样做了
typedef void (^PublicEventsHandler) (BOOL success, NSArray * _Nullable publicEvents);
当然,我同意接受的答案。
来自 apple developer blog:核心:_Nullable 和 _Nonnull
you can use the non-underscored forms nullable and nonnull immediately after an open parenthesis, as long as the type is a simple object or block pointer.
The non-underscored forms are nicer than the underscored ones, but you’d still need to apply them to every type in your header.
你也可以这样做:
- (id __nullable)methodWithArg:(NSString * __nullable)arg1
andArg:(NSString * __nonnull)arg2
completionHandler:(void (^ __nonnull)(NSArray * __nonnull results, NSError * __nullable error))completionHandler;
只看你更喜欢哪种语法。
根据Apple Blog ("Nullability and Objective-C"), 你可以使用
NS_ASSUME_NONNULL_BEGIN
和 NS_ASSUME_NONNULL_END
.
在这些区域内,任何简单的指针类型都将被假定为 nonnull
。然后你可以为可为空的对象添加 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
- 如果error是
NSError **
类型,应该是NSError * _Nullable * _Nullable
- 如果对象是
id *
类型,最好使用id _Nullable * _Nonnull
,这取决于(可能你想要_Nullable id * _Nullable
类型)。 - 如果对象是
NSObject *
类型,需要在指针后面加上注解,像这样NSObject * _Nullable * _Nonnull
备注
_Nonnull
和 _Nullable
应在指针或 id
之后使用(Apple 在示例代码 AAPLListItem * _Nullable
中这样做),但非下划线形式 nonnull
和 nullable
可以在左括号后使用。
However, in the common case there’s a much nicer way to write these annotations: within method declarations you can use the non-underscored forms
nullable
andnonnull
immediately after an open parenthesis, as long as the type is a simple object or block pointer.
在"Nullability and Objective-C"
中查看更多内容For safety, there are a few exceptions to this rule:
typedef
types don’t usually have an inherent nullability—they can easily be either nullable or non-nullable depending on the context. Therefore,typedef
types are not assumed to benonnull
, even within audited regions.- More complex pointer types like
id *
must be explicitly annotated. For example, to specify a non-nullable pointer to a nullable object reference, use_Nullable id * _Nonnull
.- The particular type
NSError **
is so often used to return errors via method parameters that it is always assumed to be a nullable pointer to a nullableNSError
reference.
_Nullable id * _Nonnull
容易混淆,id _Nullable * _Nonnull
更好理解。
_Nonnull
和 _Nullable
应在指针或 id
之后使用(Apple 在示例代码中使用 AAPLListItem * _Nullable
)