美文网首页
24.内存安全性 Memory Safety Swift官方文档

24.内存安全性 Memory Safety Swift官方文档

作者: KevinFromChina | 来源:发表于2018-03-29 18:41 被阅读0次
    //: Playground - noun: a place where people can play
    
    import UIKit
    
    // # 了解内存访问冲突
    // 使用两个访问并且满足以下条件时会发生:至少一个是写入访问;它们访问的是同一块内存;它们的访问时间重叠。
    // 两个即使访问不能同时发生.大多数访问都是即时的.
    // 长时访开始后在它结束之前其他代码依旧可以运行,这就是所谓的重叠。长时访问可以与其他长时访问以及即时访问重叠。
    
    // # 输入输出形式参数的访问冲突
    // 不能在输入输出函数中读参数,只能写
    var stepSize = 1
    func increment(_ number: inout Int) {
        number += stepSize
    }
    // there should be an error by doing: increment(&stepSize)
    // improvement: make an explicit copy
    var copyOfStepSize = stepSize
    increment(&copyOfStepSize)
    stepSize = copyOfStepSize
    
    // 一传多冲突,同时写
    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)  // OK
    // Conflicts when: balance(&playerOneScore, &playerOneScore)
    // 注意:由于操作是函数,它们同样也可以对其输入输出形式参数进行长时访问,比如,如果 balance(_:_:) 是一个名为 <^> 的操作符函数,写 playerOneScore <^> playerOneScore 就会造成和 balance(&playerOneScore, &playerOneScore) 一样的冲突。
    
    // # 在方法中对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) {
            balance(&teammate.health, &health)
        }
    }
    var oscar = Player(name: "Oscar", health: 10, energy: 10)
    var maria = Player(name: "Maria", health: 5, energy: 10)
    oscar.shareHealth(with: &maria)
    // Conflicts when: oscar.shareHealth(with: &oscar)
    
    // # 属性的访问冲突
    // 对元组的元素进行重叠写入访问就会产生冲突:
    /*
    var playerInformation = (health: 10, energy: 20)
    balance(&playerInformation.health, &playerInformation.energy) // Error
    */
    /*
     var holly = Player(name: "Holly", health: 10, energy: 10)
     balance(&holly.health, &holly.energy)  // Error
    */
    // 实际上,大多数对结构体属性的访问可以安全的重叠。
    func someFunction() {
        var oscar = Player(name: "Oscar", health: 10, energy: 10)
        balance(&oscar.health, &oscar.energy)  // OK
    }
    /* 如果下面的条件可以满足就说明重叠访问结构体的属性是安全的:
    1.只访问实例的存储属性,不是计算属性或者类属性;
    2.结构体是局部变量而非全局变量;
    3.结构体要么没有被闭包捕获要么只被非逃逸闭包捕获。
    */
    

    相关文章

      网友评论

          本文标题:24.内存安全性 Memory Safety Swift官方文档

          本文链接:https://www.haomeiwen.com/subject/wwlvcftx.html