如何在基于块的API方法中使用非空和可空的Objective-C关键字

alb*_*oli 96 xcode nullable block objective-c

考虑以下方法

- (void)methodWithArg:(NSString *)arg1 andArg:(NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
Run Code Online (Sandbox Code Playgroud)

使用new nonnullnullable annotation关键字,我们可以丰富它如下:

- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;
Run Code Online (Sandbox Code Playgroud)

但是我们也得到了这个警告:

指针缺少可为空类型说明符(__nonnull或__nullable)

它指的是第三个参数(块1).

文档未介绍如何指定块参数的可为空性的示例.它逐字陈述

只要类型是简单对象或块指针,就可以在打开括号后立即使用非下划线形式为nullable和nonnull.

我尝试将两个关键字中的一个放在块中(在任何位置),没有任何运气.还尝试了下划线前缀变体(__nonnull__nullable).

因此我的问题是:如何为块参数指定可空性语义?

Fab*_*ato 118

这似乎有效

- (void)methodWithArg:(nonnull NSString *)arg1 
  andArg:(nullable NSString *)arg2 completionHandler:(nullable void (^)
  (NSArray * _Nullable results, NSError * _Nonnull error))completionHandler
Run Code Online (Sandbox Code Playgroud)

您需要为块及其参数指定可为空性...

编辑:有关更多信息,请参阅Swift博客

  • 根据swift博客:`特殊类型NSError**经常用于通过方法参数返回错误,它总是被假定为可空的NSError引用的可空指针.https://developer.apple.com/斯威夫特/博客/?ID = 25 (3认同)

lik*_*412 30

根据Apple博客("Nullability and Objective-C"),您可以使用

NS_ASSUME_NONNULL_BEGINNS_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
Run Code Online (Sandbox Code Playgroud)
  • 如果错误NSError **类型,应该是NSError * _Nullable * _Nullable
  • 如果对象是id *类型,更好用id _Nullable * _Nonnull,它取决于(可能你想要一个_Nullable id * _Nullable类型).
  • 如果object是NSObject *type,你需要在指针之后放置注释,就像这样NSObject * _Nullable * _Nonnull

注意

_Nonnull并且_Nullable应该在指针之后使用id(Apple在示例代码中执行AAPLListItem * _Nullable),但是非下划线形式nonnull并且nullable可以在打开括号后使用.

但是,在常见的情况下,有一种更好的方法来编写这些注释:在方法声明中,只要类型是简单的对象或块指针nullable,nonnull就可以使用非下划线形式并在打开括号后立即使用.

"Nullability and Objective-C"中查看更多内容

为安全起见,此规则有一些例外:

  • typedef类型通常不具有固有的可空性 - 根据上下文,它们可以很容易地为可空或不可空.因此,即使在审计区域内,typedef也不会假设类型nonnull.
  • id *必须明确注释更复杂的指针类型.例如,要指定可空对象引用的非可空指针,请使用_Nullable id * _Nonnull.
  • 特定类型NSError **通常用于通过方法参数返回错误,因此始终假定它是可空NSError引用的可空指针.

_Nullable id * _Nonnull可以混淆,id _Nullable * _Nonnull是更好的理解.

_Nonnull并且_Nullable应该在指针之后使用id(Apple在示例代码中执行AAPLListItem * _Nullable)