TL;DR:为什么当阵列与初始值一起创建时,值会立即被取消初始化,但在创建阵列后填充阵列值会产生不同的行为?
我是在JavaScript之后学习Swift的,JavaScript有GC,所以ARC和去初始化的概念对我来说有些新手。为了更深入地理解它,我根据官方文档中的示例编写了以下代码:
// definitions; see the next two snippets for usage
class Bank {
static var coins: Int = 100 {
didSet {
let diff = coins - oldValue
let sign = diff < 0 ? "-" : "+"
print("Bank: (oldValue) (sign) (diff.magnitude) = (coins)")
}
}
static func give(_ amount: Int, to user: User) {
guard amount <= coins else {
print("[ERROR] The bank does not have enough coins; requested (amount - coins) more coins than available")
return
}
user.purse += amount
coins -= amount
}
static func take(_ amount: Int, from user: User) {
user.purse -= amount
coins += amount
}
}
class User {
private static var count = 0
let id: Int
var purse = 0
init() {
User.count += 1
id = User.count
}
deinit {
print("User #(id) perished")
Bank.take(purse, from: self)
}
}
当我用现有的用户实例(array = [value, value]
(创建数组时,去初始化发生在分配给nil
(array[0] = nil
(之后:
var users: [User?] = [
User(),
User(),
]
Bank.give(90, to: users[0]!)
users[0] = nil
Bank.give(50, to: users[1]!) // works
// Bank: 100 - 90 = 10
// User #1 perished
// Bank: 10 + 90 = 100
// Bank: 100 - 50 = 50
…但当我第一次创建一个空数组,然后用值(array = []; array[0] = value; array[1] = value
(填充它时,初始化过程会在稍后的某个随机点发生:
var users = [User?](repeating: nil, count: 2)
users[0] = User()
users[1] = User()
Bank.give(90, to: users[0]!)
users[0] = nil
Bank.give(50, to: users[1]!) // fails
// Bank: 100 - 90 = 10
// [ERROR] The bank does not have enough coins; requested 40 more coins than available
// User #1 perished
// Bank: 10 + 90 = 100
与编译器的观点有什么不同?这种差异的理由是什么?
TL;DR—不依赖于解除分配/取消初始化时间。
准确地弄清楚解除分配的时间,以及之前发生的去初始化,是一个不平凡的过程。
线程(几乎每个应用程序都是多线程的,即使它没有直接使用线程(、编译器临时性、传递值等都有助于混淆对对象的最后一次引用何时消失。
除此之外,Swift Playground本身可能会因为其工作方式而保留对对象的不明显引用,这似乎就是这里发生的事情。将您的代码放入Swift命令行应用程序对我们有效,但YMMV!
HTH-