Swift 有时方法会失败,并出现致命错误:UnsafeMutablePointer.initialize重叠范围
我用下面的代码将Swift 5中的一些Swift 有时方法会失败,并出现致命错误:UnsafeMutablePointer.initialize重叠范围,swift,unsafemutablepointer,Swift,Unsafemutablepointer,我用下面的代码将Swift 5中的一些数据解压回字符串。该方法大部分工作正常,但有时会失败,并显示以下错误消息: 线程1:致命错误:UnsafeMutablePointer.initialize重叠范围 extension Data { func decompress(destinationSize: Int) -> String? { let destinationBuffer = UnsafeMutablePointer<UInt8>.all
数据
解压回字符串
。该方法大部分工作正常,但有时会失败,并显示以下错误消息:
线程1:致命错误:UnsafeMutablePointer.initialize重叠范围
extension Data
{
func decompress(destinationSize: Int) -> String?
{
let destinationBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: destinationSize)
let decodedString = self.withUnsafeBytes
{
unsafeRawBufferPointer -> String? in
let unsafeBufferPointer = unsafeRawBufferPointer.bindMemory(to: UInt8.self)
if let unsafePointer = unsafeBufferPointer.baseAddress
{
let decompressedSize = compression_decode_buffer(destinationBuffer, destinationSize, unsafePointer, self.count, nil, COMPRESSION_ZLIB)
if decompressedSize == 0
{
return String.empty
}
let string = String(cString: destinationBuffer)
let substring = string.substring(0, decompressedSize)
return substring
}
return nil
}
return decodedString
}
}
有人能解释一下这(有时)失败的原因吗?我已切换到以下代码,现在一切正常(Swift 5):
导入压缩
扩展数据
{
func compress()->数据?
{
返回self.withUnsafeBytes
{
中的数据字节
让sourcePtr:UnsafePointer=dataBytes.baseAddress!.assumingmemorybind(to:UInt8.self)
返回self.perform(操作:压缩\流\编码,源:sourcePtr,sourceSize:self.count)
}
}
func decompress()->数据?
{
返回self.withUnsafeBytes
{
unsafeRawBufferPointer->Data?在中
让unsafeBufferPointer=unsafeRawBufferPointer.bindMemory(to:UInt8.self)
如果让unsafePointer=unsafeBufferPointer.baseAddress
{
返回self.perform(操作:压缩\流\解码,源:unsafePointer,源大小:self.count)
}
归零
}
}
fileprivate func perform(操作:压缩\流\操作,源:UnsafePointer,源大小:Int,预加载:Data=Data())->Data?
{
guard sourceSize>0 else{return nil}
让streamBase=unsafemeutablepointer.allocate(容量:1)
延迟{streamBase.deallocate()}
var stream=streamBase.pointee
let status=compression\u stream\u init(&stream,operation,compression\u ZLIB)
保护状态!=压缩状态错误{return nil}
延迟{compression\u stream\u destroy(&stream)}
var结果=预加载
变量标志:Int32=Int32(压缩\u流\u FINALIZE.rawValue)
设blockLimit=64*1024
var bufferSize=Swift.max(sourceSize,64)
如果sourceSize>blockLimit
{
缓冲区大小=块限制
}
let buffer=unsafemeutablepointer.allocate(容量:bufferSize)
延迟{buffer.deallocate()}
stream.dst_ptr=缓冲区
stream.dst_size=缓冲区大小
stream.src_ptr=源
stream.src_size=sourceSize
虽然是真的
{
交换机压缩\u流\u进程(&流,标志)
{
案例压缩\u状态\u正常:
guard stream.dst_size==0 else{return nil}
追加(缓冲区,计数:stream.dst_ptr-buffer)
stream.dst_ptr=缓冲区
stream.dst_size=缓冲区大小
如果标志==0&&stream.src\u大小==0
{
flags=Int32(压缩\u流\u FINALIZE.rawValue)
}
案例压缩\u状态\u结束:
追加(缓冲区,计数:stream.dst_ptr-buffer)
返回结果
违约:
归零
}
}
}
}
我已切换到以下代码,现在一切正常(Swift 5):
导入压缩
扩展数据
{
func compress()->数据?
{
返回self.withUnsafeBytes
{
中的数据字节
让sourcePtr:UnsafePointer=dataBytes.baseAddress!.assumingmemorybind(to:UInt8.self)
返回self.perform(操作:压缩\流\编码,源:sourcePtr,sourceSize:self.count)
}
}
func decompress()->数据?
{
返回self.withUnsafeBytes
{
unsafeRawBufferPointer->Data?在中
让unsafeBufferPointer=unsafeRawBufferPointer.bindMemory(to:UInt8.self)
如果让unsafePointer=unsafeBufferPointer.baseAddress
{
返回self.perform(操作:压缩\流\解码,源:unsafePointer,源大小:self.count)
}
归零
}
}
fileprivate func perform(操作:压缩\流\操作,源:UnsafePointer,源大小:Int,预加载:Data=Data())->Data?
{
guard sourceSize>0 else{return nil}
让streamBase=unsafemeutablepointer.allocate(容量:1)
延迟{streamBase.deallocate()}
var stream=streamBase.pointee
let status=compression\u stream\u init(&stream,operation,compression\u ZLIB)
保护状态!=压缩状态错误{return nil}
延迟{compression\u stream\u destroy(&stream)}
var结果=预加载
变量标志:Int32=Int32(压缩\u流\u FINALIZE.rawValue)
设blockLimit=64*1024
var bufferSize=Swift.max(sourceSize,64)
如果sourceSize>blockLimit
{
缓冲区大小=块限制
}
let buffer=unsafemeutablepointer.allocate(容量:bufferSize)
延迟{buffer.deallocate()}
stream.dst_ptr=缓冲区
stream.dst_size=缓冲区大小
stream.src_ptr=源
stream.src_size=sourceSize
虽然是真的
{
交换机压缩\u流\u进程(&流,标志)
{
案例压缩\u状态\u正常:
guard stream.dst_size==0 else{return nil}
追加(缓冲区,计数:stream.dst_ptr-buffer)
stream.dst_ptr=缓冲区
stream.dst_size=缓冲区大小
如果标志==0&&stream.src\u大小==0
{
flags=Int32(压缩\u流\u FINALIZE.rawValue)
}
案例压缩\u状态\u结束:
追加(缓冲区,计数:stream.dst_ptr-buffer)
返回
let string = String(cString: destinationBuffer)
import Compression
extension Data
{
func compress() -> Data?
{
return self.withUnsafeBytes
{
dataBytes in
let sourcePtr: UnsafePointer<UInt8> = dataBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
return self.perform(operation: COMPRESSION_STREAM_ENCODE, source: sourcePtr, sourceSize: self.count)
}
}
func decompress() -> Data?
{
return self.withUnsafeBytes
{
unsafeRawBufferPointer -> Data? in
let unsafeBufferPointer = unsafeRawBufferPointer.bindMemory(to: UInt8.self)
if let unsafePointer = unsafeBufferPointer.baseAddress
{
return self.perform(operation: COMPRESSION_STREAM_DECODE, source: unsafePointer, sourceSize: self.count)
}
return nil
}
}
fileprivate func perform(operation: compression_stream_operation, source: UnsafePointer<UInt8>, sourceSize: Int, preload: Data = Data()) -> Data?
{
guard sourceSize > 0 else { return nil }
let streamBase = UnsafeMutablePointer<compression_stream>.allocate(capacity: 1)
defer { streamBase.deallocate() }
var stream = streamBase.pointee
let status = compression_stream_init(&stream, operation, COMPRESSION_ZLIB)
guard status != COMPRESSION_STATUS_ERROR else { return nil }
defer { compression_stream_destroy(&stream) }
var result = preload
var flags: Int32 = Int32(COMPRESSION_STREAM_FINALIZE.rawValue)
let blockLimit = 64 * 1024
var bufferSize = Swift.max(sourceSize, 64)
if sourceSize > blockLimit
{
bufferSize = blockLimit
}
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
defer { buffer.deallocate() }
stream.dst_ptr = buffer
stream.dst_size = bufferSize
stream.src_ptr = source
stream.src_size = sourceSize
while true
{
switch compression_stream_process(&stream, flags)
{
case COMPRESSION_STATUS_OK:
guard stream.dst_size == 0 else { return nil }
result.append(buffer, count: stream.dst_ptr - buffer)
stream.dst_ptr = buffer
stream.dst_size = bufferSize
if flags == 0 && stream.src_size == 0
{
flags = Int32(COMPRESSION_STREAM_FINALIZE.rawValue)
}
case COMPRESSION_STATUS_END:
result.append(buffer, count: stream.dst_ptr - buffer)
return result
default:
return nil
}
}
}
}