malloc
и free
на самом деле отлично работают в Swift; однако API UnsafeMutablePointer
более "родной". Я бы, вероятно, использовал Data
bytesNoCopy
для лучшей производительности. Если вы хотите, вы можете использовать Data(bytes:count:)
, но это сделает копию данных (а затем вам нужно обязательно освободить указатель после создания копии, иначе вы потеряете память, что на самом деле является проблемой в код Objective-C выше, так как он не может free
буфер).
Итак, что-то вроде:
func prepareEndPacket() -> Data {
let count = PACKET_SIZE + 5
let buf = UnsafeMutablePointer<UInt8>.allocate(capacity: count)
PrepareEndPacket(buf)
return Data(bytesNoCopy: buf, count: count, deallocator: .custom { ptr, _ in
ptr.deallocate()
})
}
Используя bytesNoCopy
, возвращаемый объект Data
по сути является оберткой вокруг исходного указателя, которая освобождается деллокацией при уничтожении объекта Data
.
Кроме того, вы можете создать объект Data
с нуля и получить указатель на его содержимое для передачи на PrepareEndPacket()
:
func prepareEndPacket() -> Data {
var data = Data(count: PACKET_SIZE + 5)
data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
PrepareEndPacket(ptr)
}
return data
}
Это немного менее эффективно, поскольку инициализатор Data(count:)
инициализирует все байты Data
в ноль (аналогично использованию calloc
вместо malloc
), но во многих случаи, которые могут не иметь достаточного значения, чтобы иметь значение.