我有一个以前在Swift 3中可用的方法。它是BZCompression算法的端口。该方法分配内存以对其进行压缩,并使其在运行时可用。使用Xcode 10.1时,代码无法编译。该方法会重新评估内存以运行算法,这在swift中是不允许的,但在swift 4中是更严格的。
这是我在Xcode中收到的错误消息: 对“ buff”的访问重叠,但是修改需要排他访问;考虑复制到本地变量
var bzCompressedData: Data? {
get {
if self.count == 0 {
return self
}
var compressed = [UInt8]()
var stream = bz_stream()
var mself = self
var success = true
mself.withUnsafeMutableBytes { (selfBuff: UnsafeMutablePointer<Int8>) -> Void in
stream.next_in = selfBuff
stream.avail_in = UInt32(self.count)
var buff = Data(capacity: Int(BZCompressionBufferSize))
var copyBuff = buff
copyBuff.withUnsafeMutableBytes({ (outBuff: UnsafeMutablePointer<Int8>) -> Void in
stream.next_out = outBuff
stream.avail_out = BZCompressionBufferSize
var bzret = BZ2_bzCompressInit(&stream, BZDefaultBlockSize, 0, BZDefaultWorkFactor)
if bzret != BZ_OK {
print("failed compression init")
success = false
return
}
repeat {
bzret = BZ2_bzCompress(&stream, stream.avail_in > 0 ? BZ_RUN : BZ_FINISH)
if bzret < BZ_OK {
print("failed compress")
success = false
return
}
buff.withUnsafeBytes({ (bp: UnsafePointer<UInt8>) -> Void in
let bpp = UnsafeBufferPointer(
start: bp, count: (Int(BZCompressionBufferSize) - Int(stream.avail_out)))
compressed.append(contentsOf: bpp)
})
stream.next_out = outBuff
stream.avail_out = BZCompressionBufferSize
} while bzret != BZ_STREAM_END
})
}
BZ2_bzCompressEnd(&stream)
if !success {
return nil
}
return Data(bytes: compressed)
}
}
这设法允许进行编译,但是我可以看到原始缓冲区已过度分配并在运行时崩溃。