将 Objective-C malloc 转换为 Swift
Posted
技术标签:
【中文标题】将 Objective-C malloc 转换为 Swift【英文标题】:Converting Objective-C malloc to Swift 【发布时间】:2018-11-09 20:10:13 【问题描述】:我正在开发一个用 Objective-C 编写的项目,需要更新到 Swift。我们使用 C 文件来传输数据。
这是我在 Objective-C 中给出的代码:
- (NSData *)prepareEndPacket
UInt8 *buff_data;
buff_data = (uint8_t *)malloc(sizeof(uint8_t)*(PACKET_SIZE+5));
// Call to C File
PrepareEndPacket(buff_data);
NSData *data_first = [NSData dataWithBytes:buff_data length:sizeof(uint8_t)*(PACKET_SIZE+5)];
return data_first;
在 C .h 文件中,我有这个供参考:
#define PACKET_SIZE ((uint32_t)128)
我似乎找不到将其转换为 Swift 的好方法。任何帮助,将不胜感激。
【问题讨论】:
该代码将泄漏 malloc 的数据。它应该使用dataWithBytesNoCopy
来创建NSData
对象而不是dataWithBytes
,以便NSData
对象拥有malloc
'ed 数据缓冲区的所有权。
【参考方案1】:
malloc
和 free
实际上在 Swift 中运行良好;但是,UnsafeMutablePointer
API 更“原生”。我可能会使用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
),但在在很多情况下,这可能并不足以产生影响。
【讨论】:
优秀答案(已投票)。您可能想详细了解 Objective-C 代码泄漏的原因。 @Charles Srstka 我还有一个部分可能需要帮助。它使用 memcpy @temp_ 发表一个新问题,我会看看。以上是关于将 Objective-C malloc 转换为 Swift的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C:如何将 NSIndexSet 转换为 NSIndexPath