如果我通过将self分配给一些外部强引用而从deinit中走私出了怎么办?下面的代码显然格式不正确:

class C: CustomStringConvertible {
    let s = "abc"

    var description: String {
        return "C(id: \(ObjectIdentifier(self)), s: \(s))"
    }

    deinit {
        print("deinit")
        globalObject = self
    }
}

var globalObject: C!

do {
    let localObject = C()
    print("localObject: \(localObject)")
    print("end of `do`")
}

print("globalObject: \(globalObject!)")

您不能只是从deinit的中间“改变主意”关于对象的取消初始化。但有趣的是,此代码是不确定的,有时偶尔会成功完成,并打印:
localObject: C(id: ObjectIdentifier(0x00007f9063f00960), s: abc)
end of `do`
deinit
globalObject: C(id: ObjectIdentifier(0x00007f9063f00960), s: abc)

我使用Code Runner运行此程序,后者仅使用swiftc运行单个文件Swift脚本。因此,这里没有任何Playground拥有的意外引用。

不确定性从何而来?

最佳答案

这不是答案,但是评论太久了:
有趣的是,我只是附加了:

for _ in 1...1000000 {
    print("intermediate: \(globalObject!)")
}
print("globalObject: \(globalObject!)")
进而:
swiftc test.swift
for ((i = 0; i < 10000; i++)); do
    ./test  | fgrep globalObject
done
我得到的是(在这10000次运行中只有一次):

下一轮:

看来有些比赛条件,但是我不知道谁在这里产生线程。
顺便提一句:
swiftc -version
Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.7.0

关于swift - 从 `self`中走私 `deinit`,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57912403/

10-10 08:18