swiftSwift

Swift - Memory Safety

2018-10-31  本文已影响29人  ienos

默认,Swift 会阻止不安全行为

不安全行为
Swift 做了什么?
我们该做什么?
访问冲突的简单例子

购物时新增购物项目的两个步骤

内存中变化状态

在 During 中总购物项目发生改变,但是金额总数却未发生改变,将会读取到错误信息。我们可能会根据多种方式去修复冲突产生不同结果,根据实际情况获取我们所要的正确金额(有可能是 Before Account,也有可能是 After Account)

下面讨论的都是单线程问题,并发和多线程冲突访问也许会出现相同问题

内存访问特性

两个访问发生冲突的所有条件
instantaneous & long - term
Conflicting Access - In-Out 参数
var stepSize = 1
func increment(_ number: inout Int) { // write number 
    number += stepSize // read stepSize
}

increment(&stepSize) // Error: conflicting accesses to stepSize
print("\(stepSize)")

解决方法

var copyOfStepSize = stepSize // copy
increment(&copyOfStepSize)
stepSize = copyOfStepSIze
同一个变量传多个 inout 参数
func balance(_ x: inout Int, _ y: inout Int) { 
    let sum = x + y
    x = sum / 2
    y = sum - x
}

var playerOneScore = 42
var playerTwoScore = 30
balance(&playerOneScore, &playerTwoScore) // Success
balance(&playerOneScore, &playerOneScore) // Error

Conflicting Access - SELF

struct Player {    
    var name: String
    var health: Int
    var energy: Int
  
    static let maxHealth = 10
    mutating func restoreHealth() {  
        health = Player.maxHealth
    }
}

extension Player {
    mutating func shareHealth(with teammate: inout Player) { // write teammate
        balance(&teammate.health, &health) // write self 
    }
}

var oscar = Player(name: "Oscar", health: 10, energy: 10)
var maria = Player(name: "Maria", health: 5, energy: 10)
oscar.shareHealth(with: &maria) // OK
oscar.shareHealth(with: &oscar) // Error

Conflicting Access - Property

一个写的操作到元祖元素需要写入整个元祖。意味着他们有两个访问到 playerInformation 在重叠的区间,造成冲突

var playerInformation = (health: 10, energy: 20)
balance(&playerInformation.health, &playerInformation.energy)
// Error: Conflicting access property of playerInformation 
当不是全局变量而是局部变量时是安全的
func someFunction() {
     var oscar = Player(name: "Oscar", health: 10, energy: 10)
     balance(&oscar.health, &oscar.energy) // OK
}

👇几种情况访问结构体的属性是安全的

上一篇 下一篇

猜你喜欢

热点阅读