【问题标题】:Overlapping accesses to "result", but modification requires exclusive access; consider copying to a local variable in xcode 10对“结果”的访问重叠,但修改需要独占访问;考虑复制到 xcode 10 中的局部变量
【发布时间】:2018-06-07 07:39:38
【问题描述】:
open static func PBKDF2(_ password: String, salt: Data,
                        prf: PRFAlg, rounds: UInt32) throws -> Data {
    var result = Data(count:prf.cc.digestLength)
    let passwData = password.data(using: String.Encoding.utf8)!
    let status = result.withUnsafeMutableBytes { (passwDataBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
        return CCKeyDerivationPBKDF!(
            PBKDFAlgorithm.pbkdf2.rawValue,
            (passwData as NSData).bytes, 
            passwData.count,
            (salt as NSData).bytes, 
            salt.count,
            prf.rawValue,
            rounds,
            passwDataBytes,
            result.count)
     }

     guard status == noErr else { throw CCError(status) }

     return result
}

result.withUnsafeMutableBytes 在 Xcode 10 中给出错误,在 Xcode 9 中是警告。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    这是SE-0176 Enforce Exclusive Access to Memory 的结果,它在 Swift 4 中实现 并且在 Swift 4.2 中更加严格。

    解决方案是将计数分配给单独的变量:

    let count = result.count
    let status = result.withUnsafeMutableBytes {
        (passwDataBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
            return CCKeyDerivationPBKDF(..., count)
    }
    

    或在捕获列表中捕获计数:

    let status = result.withUnsafeMutableBytes { [ count = result.count ]
        (passwDataBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
            return CCKeyDerivationPBKDF(..., count)
    }
    

    另请参阅 Swift 论坛中的 Overlapping access warning in withUnsafeMutableBytes

    hamishknight:

    withUnsafeMutableBytes(_:) 是 Data 的变异方法,因此它需要在调用期间对数据进行写访问。通过访问闭包中的 data.count,您将开始对与当前写入访问冲突的数据进行新的读取。

    Joe_Groff:

    您还可以在闭包的捕获列表中捕获数据的副本或其计数:...

    在形成闭包时,在独占访问开始之前,对捕获列表进行评估并按值捕获结果,避免重叠访问。

    和this comment 对应的拉取请求:

    这里一个适当的解决方法是将缓冲区的计数复制到闭包之外并将其传递给 inet_ntop()。

    Swift 5 更新:

    let status = result.withUnsafeMutableBytes { [ count = result.count ]
        (bufferPointer) -> CCCryptorStatus in
        let passwDataBytes = bufferPointer.bindMemory(to: UInt8.self).baseAddress
        return CCKeyDerivationPBKDF(..., passwDataBytes, count)
    }
    

    【讨论】:

    • 当我尝试capture list 时,错误是Use of unresolved identifier _count_
    • @javadba: _count_ 带下划线?我想知道这是从哪里来的。
    • 这仅用于格式化(用于 SOF 评论) - 应该是 count 。我无法使用 capture list 方法:它给出了语法错误。我最终在withUnsfafeMutableBytes 之前使用本地副本代替count
    • @javadba:如果你有一个 GitHub Gist 和一些独立的代码来演示问题,那么我可以看看它。
    猜你喜欢
    • 1970-01-01
    • 2019-05-30
    • 2018-02-17
    • 2019-01-11
    • 2018-03-07
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 2018-01-07
    相关资源
    最近更新 更多