【问题标题】:How does a non optional value obtain a nil value?非可选值如何获得 nil 值?
【发布时间】:2017-07-22 06:12:21
【问题描述】:

Apple documentation TN2151 说这可能是导致 EXC_BREAKPOINT / SIGTRAP 的原因:

具有 nil 值的非可选类型

但是这样的代码不会编译:

var x = "hello"
x = nil

那么在什么情况下非可选可以获取nil的值呢?

【问题讨论】:

标签: swift


【解决方案1】:

考虑在 Objective-C 中桥接到 Swift 中的类似内容:

- (NSObject * _Nonnull)someObject {
    return nil;
}

该函数被注释为_Nonnull,但将返回nil。这作为非可选对象桥接到 Swift 并且会崩溃。

【讨论】:

  • 这是最常见的原因。有一堆 iOS(和 macOS)API 被错误地标记为 _Nonnull
  • 参见 AppKit Release Notes for macOS 10.13 中标题为“Nullability”的部分:“我们修复了一些参数和返回值具有不正确的 Nullability 的地方。”
【解决方案2】:

做作,但可能:

class C {}

let x: C? = nil
let y: C = unsafeBitCast(x, to: C.self)

print(y) // boom

【讨论】:

  • 或者只是unsafeBitCast(0, to: C.self)
  • 回到 [Objective-]C 的演员阵容中,向自己的脚开枪,总是优雅的 :)
  • 注解:unsafeBitCast 成功是因为对于引用类型,CC? 的实例是指针,因此大小相同。使用struct C {},unsafeBitCast 已经崩溃(不能在不同大小的类型之间使用 unsafeBitCast)。
  • @MartinR 是的。这是我真正喜欢的东西,在大多数结构的情况下,Optional 是一个包含鉴别器和有效负载结构的元组,而在类的情况下,Optionalnil 值打包为 0 指针
【解决方案3】:

在与 Objective C 互操作时发生。一个 objc 方法可以注释为 nonnull,但无论如何都不会阻止它返回 nil。编译器只捕获最明显的情况,即使那样它也只会产生警告(例如,当你在指定为不返回 nil 的方法中明目张胆地 return nil; 时。)

【讨论】:

    【解决方案4】:

    我不确定,但是如果您像这样将 Optional 强制解包 (!) 到 Non-Optional 变量中,可能会发生这种情况:

    let a : String? = nil
    var x = "hello"
    x = a!
    

    但这只是猜测......

    【讨论】:

    • 这仍然使用可选项。 OP 正在询问非可选类型的崩溃。
    • 其实你的程序会因为fatal error: unexpectedly found nil while unwrapping an Optional value.而崩溃
    • @AnhTrungPham 会因为 OP 在他们的问题中所说的不同原因而崩溃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多