由于两个存储的属性在Swift中不以任何方式交互,因此如何保持内存安全?
import UIKit
var robGlobal = Player(name: "Rob", health: 10, energy: 10)
var matt = Player(name: "Matt", health: 5, energy: 10)
struct Player {
var name: String
var health: Int
var energy: Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
}
func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK1: -Conflicting Access to self in Methods
robGlobal.shareHealth(with: &matt)
robGlobal.shareHealth(with: &robGlobal) // NOT OK in compile time Error: //Overlapping accesses to 'robGlobal', but modification requires exclusive access; consider copying to a local variable
var robNewLocal = Player(name: "Rob", health: 10, energy: 10)
robNewLocal.shareHealth(with: &robNewLocal) // NOT OK in compile time
//MARK2: -Conflicting Access to properties in Methods
robGlobal.someFunction() // OK
robGlobal.anotherFunction() // NOT OK in Run Time Error: Thread 1: Simultaneous accesses to 0x108cc4050, but modification requires exclusive access
}
}
extension Player {
mutating func shareHealth(with teammate: inout Player) {
balance(&teammate.health, &health)
}
func someFunction() {
var robLocal = Player(name: "Rob", health: 10, energy: 10)
balance(&robLocal.health, &robLocal.energy) // OK
}
func anotherFunction() {
balance(&robGlobal.health, &robGlobal.energy) // NOT OK in Run Time
}
}
我试图了解 Swift 中的内存安全,我在两种情况之间感到困惑。
正如我在方法部分标记的MARK1: -Conflicting Access to self是有道理的。两次写访问相互重叠。在运行之前编译器已经给了我错误:
'robGlobal' 的重叠访问,但修改需要独占访问;考虑复制到局部变量
问题一:好的,但是MARK2部分呢?Swift 编译器进行了一些优化来解决这里对 struct 的写访问?
苹果解释说明如下解决方案,但我不清楚。
编译器可以证明保留了内存安全,因为这两个存储的属性不会以任何方式交互。
问题二:通过使全局运行时问题解决。但我想知道如何?还有为什么它不适用于 MARK1 部分,为什么?
PS:苹果文档在这里