在Objective-C中,您可以将NULL
传递给任何NSError**
参数以忽略该错误。但是,当我尝试将NULL
传递给抛出错误的Swift方法时,它会生成运行时错误。
// Thrower.swift
class Thrower: NSObject {
static func throwError() throws {
throw NSError(domain: "bla", code: 0, userInfo: nil)
}
}
...
// AppDelegate.m
BOOL success = [Thrower throwErrorAndReturnError:NULL];
这会产生EXC_BAD_INSTRUCTION
错误,包含此堆栈:
我对这种行为感到有些惊讶。我希望这可以工作,或者编译器在将NULL
传递给其中一个方法时生成警告。
这是Swift方法生成的标题的样子:
+ (BOOL)throwErrorAndReturnError:(NSError * __nullable * __null_unspecified)error;
如果这不起作用,为什么他们不会生成NSError * __nullable * __nonnull
,以便在您尝试传入可空的NSError*
时生成编译器警告?
我在这里缺少什么,或者这只是预期的行为?
答案 0 :(得分:1)
On WWDC'15 Session 401(Swift和Objective-C互操作性)Doug Gregor说:
这意味着,“我想到了,我无法回答。”最好的办法是在Swift中保持隐式解包可选,在此处保持null-unspecified。
所以,基本上,你的null被映射到ImplicitlyUnwrappedOptional<ErrorType>.None
,这几乎解释了崩溃。
在上面的会话中,他们提到两个指针上的NSError **
被假定为nullable
。显然他们已经改变了主意,或者地图不对称,无论如何我看起来都不对。
考虑到这种行为而不是NSError * __nullable * __nonnull
我会说这是一个错误,我会打开一个雷达。如果你这样做,请告诉我们,以便我们可以欺骗它。