Ios C数组内存从swift释放

Ios C数组内存从swift释放,ios,macos,swift,interop,xcode6,Ios,Macos,Swift,Interop,Xcode6,您好,我正在调用上面的C APIhost\u processor\u info从swift获取进程加载信息,没有问题。 cpuInfo是一个inout参数(指针),返回时将指向包含该API分配的CPU信息的结构。 调用方负责释放内存;我可以从目标C轻松做到这一点,但在斯威夫特没有任何运气。我知道我可以把这个调用包装成一个objective C扩展,但我正在尝试学习swift,如果可能的话,我希望避免使用obj-C解决方案 在obj-c中,我将取消分配: var cpuInfo: processo

您好,我正在调用上面的C API
host\u processor\u info
从swift获取进程加载信息,没有问题。
cpuInfo
是一个inout参数(指针),返回时将指向包含该API分配的CPU信息的结构。 调用方负责释放内存;我可以从目标C轻松做到这一点,但在斯威夫特没有任何运气。我知道我可以把这个调用包装成一个objective C扩展,但我正在尝试学习swift,如果可能的话,我希望避免使用obj-C解决方案

在obj-c中,我将取消分配:

var cpuInfo: processor_info_array_t = nil
var numCpuInfo: mach_msg_type_number_t = 0
var coresTotalUsage: Float = 0.0
var numCPUsU: natural_t = 0
let err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUsU, &cpuInfo, &numCpuInfo);
assert(err == KERN_SUCCESS, "Failed call to host_processor_info")
swift中的cpuInfo是一个不可分配的指针,不能转换为vm_地址


非常感谢您的帮助。

处理器信息数组是指针类型,
虚拟机地址是整数类型
(最终为
UInt
的别名)。(从
这可能是出于历史原因。) 在Swift中将指针转换为整数(大小相同)的唯一方法是
unsafeBitCast

mach_init.h
定义

size_t cpuInfoSize = sizeof(integer_t) * numCpuInfo;
vm_deallocate(mach_task_self(), (vm_address_t) cpuInfo, cpuInfoSize)
只有extern变量在Swift中可见,而宏中不可见

这使得:

extern mach_port_t      mach_task_self_;
#define mach_task_self() mach_task_self_

在Swift 4中,等效代码为:

let cpuInfoSize = vm_size_t(sizeof(integer_t)) * vm_size_t(numCpuInfo)
vm_deallocate(mach_task_self_, unsafeBitCast(cpuInfo, vm_address_t.self), cpuInfoSize)
让cpuInfoSize=vm\u size\u t(MemoryLayout.stride*Int(numpuinfo))
vm_解除分配(mach_任务_自身_、vm_地址_t(位模式:cpuInfo)、cpuInfoSize)

特别是,初始化器
UInt(位模式:)
现在显然比
unsafeBitCast()
更适合使用指针的位模式初始化无符号整数(我想这种用法不再被认为是“不安全的”)。它正确地处理一个
nil
指针,在这种情况下返回0。

var prevCpuInfoSize:vm\u size\u t=UInt(UInt32(sizeof(integer\u t))*numPrevCpuInfo)作为vm\u size\u vm\u deallocate(mach\u task\u self\u,unsafeBitCast(prevCpuInfo,vm\u address\u t.self),prevCpuInfoSize)
谢谢Martin!小的修改,但这几乎是工作,没有更多的内存泄漏。我不太明白为什么只有extern变量在swift中可见,而宏不可见。@Pippo:有些(目标-)C宏是导入的,有些不是,比较一下。@Pippo:你说得对,我忘记了乘法。我已经更新了答案,作为未来读者的参考。这在Swift 3.1中仍然有效。只是想说声谢谢,马丁@很高兴知道,谢谢你的确认!
let cpuInfoSize = vm_size_t(MemoryLayout<integer_t>.stride * Int(numCpuInfo))
vm_deallocate(mach_task_self_, vm_address_t(bitPattern: cpuInfo), cpuInfoSize)