我习惯使用这个宏来初始化NSError**
参数:
#define INIT_ERROR_IF_NULL(error) error = error ? error : &(NSError*){ nil }
这将检查传递的NSError**
参数,如果是NULL
,则将其初始化为虚拟对象NSError
,这样我就不必将每个*error
取消引用都包装在条件中。在代码中,这个版本:
- (void) doFoo: (NSError**) error
{
if (error) {
*error = [NSError …];
}
}
…变成这样:
- (void) doFoo: (NSError**) error
{
INIT_ERROR_IF_NULL(error);
*error = [NSError …];
}
error
我喜欢这种方法,它可以节省分支并让我编写更少的代码(当然,当只使用一次时我不会打扰)。问题是它在最近的 Clang 版本中停止工作,因为编译器抱怨指针类型不匹配:
Pointer type mismatch ('NSError *__autoreleasing *' and 'NSError **')
如果我更改宏以将生成的匿名对象显式转换为NSError *__autoreleasing*
(类型签名变得荒谬),编译器会在另一行进一步抱怨:
Casting 'NSError **' to type 'NSError *__autoreleasing *' changes retain/release properties of pointer
同样,有问题的变量是一个方法参数。我不明白这个问题。我可以做些什么来保留我的宏?