Swift MACH_任务_基本信息的快速指针问题
我试图将ObjC stackoverflow答案转换为Swift和failing。看起来我正在传递一个Swift MACH_任务_基本信息的快速指针问题,swift,mach,Swift,Mach,我试图将ObjC stackoverflow答案转换为Swift和failing。看起来我正在传递一个不可分配指针,而我应该在传递一个输入的mach\u msg\u type\u number\u t时,我似乎无法解决我的问题。根据我对Swift指针文档的理解(不是很多),这些应该是可互换的 更多信息见下文 以下是目标C: struct task_basic_info info; mach_msg_type_number_t size = sizeof(info); kern_return_t
不可分配指针
,而我应该在传递一个输入的mach\u msg\u type\u number\u t
时,我似乎无法解决我的问题。根据我对Swift指针文档的理解(不是很多),这些应该是可互换的
更多信息见下文
以下是目标C:
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
这是我在Swift中得到的最新信息(许多行用于更容易的类型检查)
任务信息
签名为:
func task_info(target_task: task_name_t, flavor: task_flavor_t, task_info_out: task_info_t, task_info_outCnt: UnsafeMutablePointer<mach_msg_type_number_t>) -> kern_return_t
当与C函数交互时,您不能依赖编译器的错误消息—逐个参数分解它,单击命令直到您知道正在使用什么。首先,您遇到的类型有:
:task\u name\u t
UInt32
:task\u flavor\t
UInt32
:task\u info\u t
非女性化指针
:非女性化指针
非女性化指针
-kern\u return\t
Int32
task\u info\u out
参数需要是一个unassemutablepointer
,但需要实际指向mach\u task\u basic\u info
的实例。我们可以通过创建一个UnsafeMutablePointer
并在调用时将其包装在另一个UnsafeMutablePointer
中来解决这个问题-编译器将使用类型推断来知道我们希望包装指针被子类型化为UInt32
第二,当您应该调用sizeinfo(mach\u task\u basic\u info)
时,您正在调用sizeof(mach\u task\u basic\u info)
(指向mach\u task\u basic\u info的指针),因此字节计数太低,无法保存数据结构
在进一步的研究中,这变得有点复杂。这方面的原始代码不正确,因为size
应初始化为常量MACH\u TASK\u BASIC\u INFO\u COUNT
。不幸的是,这是一个宏,而不是一个简单的常量:
#define MACH_TASK_BASIC_INFO_COUNT (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))
斯威夫特不进口这些,所以我们需要自己重新定义它。以下是所有这些的工作代码:
// constant
let MACH_TASK_BASIC_INFO_COUNT = (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))
// prepare parameters
let name = mach_task_self_
let flavor = task_flavor_t(MACH_TASK_BASIC_INFO)
var size = mach_msg_type_number_t(MACH_TASK_BASIC_INFO_COUNT)
// allocate pointer to mach_task_basic_info
var infoPointer = UnsafeMutablePointer<mach_task_basic_info>.alloc(1)
// call task_info - note extra UnsafeMutablePointer(...) call
let kerr = task_info(name, flavor, UnsafeMutablePointer(infoPointer), &size)
// get mach_task_basic_info struct out of pointer
let info = infoPointer.move()
// deallocate pointer
infoPointer.dealloc(1)
// check return value for success / failure
if kerr == KERN_SUCCESS {
println("Memory in use (in bytes): \(info.resident_size)")
} else {
let errorString = String(CString: mach_error_string(kerr), encoding: NSASCIIStringEncoding)
println(errorString ?? "Error: couldn't parse error string")
}
//常数
设MACH_TASK_BASIC_INFO_COUNT=(sizeof(MACH_TASK_BASIC_INFO_data)/sizeof(natural_t))
//准备参数
让name=mach\u task\u self_
让味道=任务味道(马赫任务基本信息)
变量大小=马赫数信息类型编号(马赫数任务基本信息计数)
//分配指向马赫数任务基本信息的指针
var infoPointer=unsafemeutablepointer.alloc(1)
//调用任务\u信息-注意额外的不可配置指针(…)调用
让kerr=任务信息(名称、风格、非女性化指针(infoPointer)和大小)
//从指针中获取马赫任务基本信息结构
let info=infoPointer.move()
//释放指针
infoPointer.dealloc(1)
//检查返回值是否成功/失败
如果kerr==KERN_成功{
println(“正在使用的内存(字节):\(info.resident\u size)”)
}否则{
let errorString=String(CString:mach_error_String(kerr),编码:NSASCIIStringEncoding)
println(错误字符串??“错误:无法分析错误字符串”)
}
内特的答案很好,但你可以做一些调整来简化它
首先,您可以在堆栈上创建结构,而不是分配/取消分配task\u basic\u info
指针,然后使用withUnsafeMutablePointer
直接获取指向它的指针,您可以传入该指针
func report_memory() {
var info = mach_task_basic_info()
var count = mach_msg_type_number_t(sizeofValue(info))/4
let kerr: kern_return_t = withUnsafeMutablePointer(&info) {
task_info(mach_task_self_,
task_flavor_t(MACH_TASK_BASIC_INFO),
task_info_t($0),
&count)
}
if kerr == KERN_SUCCESS {
println("Memory in use (in bytes): \(info.resident_size)")
}
else {
println("Error with task_info(): " +
(String.fromCString(mach_error_string(kerr)) ?? "unknown error"))
}
}
我花了一点时间将空速的答案更新为最新的swift语法(swift 3,beta 6),但我得到的是:
func report_memory() {
var info = mach_task_basic_info()
let MACH_TASK_BASIC_INFO_COUNT = MemoryLayout<mach_task_basic_info>.stride/MemoryLayout<natural_t>.stride
var count = mach_msg_type_number_t(MACH_TASK_BASIC_INFO_COUNT)
let kerr: kern_return_t = withUnsafeMutablePointer(to: &info) {
$0.withMemoryRebound(to: integer_t.self, capacity: MACH_TASK_BASIC_INFO_COUNT) {
task_info(mach_task_self_,
task_flavor_t(MACH_TASK_BASIC_INFO),
$0,
&count)
}
}
if kerr == KERN_SUCCESS {
print("Memory in use (in bytes): \(info.resident_size)")
}
else {
print("Error with task_info(): " +
(String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error"))
}
}
func报告_内存(){
var info=马赫数任务基本信息()
让MACH_TASK_BASIC_INFO_COUNT=MemoryLayout.stride/MemoryLayout.stride
变量计数=马赫数信息类型编号(马赫数任务基本信息计数)
让kerr:kern\u返回\u t=withUnsafeMutablePointer(to:&info){
$0.withMemoryRebound(收件人:整数\u t.self,容量:马赫\u任务\u基本信息\u计数){
任务信息(机器任务自身),
任务风格(马赫任务基本信息),
$0,
&计数)
}
}
如果kerr==KERN_成功{
打印(“正在使用的内存(字节):\(info.resident\u size)”)
}
否则{
打印(“任务信息错误:”+
(字符串(cString:mach_error_String(kerr),编码:String.encoding.ascii)??“未知错误”))
}
}
希望这会有帮助。Swift 3中空速速度的答案
func GetMemory()
{
var info = mach_task_basic_info()
var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info))/4
let kerr: kern_return_t = withUnsafeMutablePointer(to: &info)
{
task_info(mach_task_self_,
task_flavor_t(MACH_TASK_BASIC_INFO),
$0.withMemoryRebound(to: Int32.self, capacity: 1) { zeroPtr in
task_info_t(zeroPtr)
},
&count)
}
if kerr == KERN_SUCCESS {
print("Memory in use (in bytes): \(info.resident_size)")
}
else {
print("Error with task_info(): " +
(String.init(validatingUTF8: mach_error_string(kerr)) ?? "unknown error"))
}
}
Swift 5+联合收割机,连续记忆监控
以MB为单位显示精确内存,如XCODE
import Foundation
import Combine
enum MemoryMonitorState {
case started
case paused
}
class MemoryUsageCustom {
private var displayLink: CADisplayLink!
var state = MemoryMonitorState.paused
let subject = PassthroughSubject<String, Never>()
private static var sharedInstance: MemoryUsageCustom!
public class func shared() -> MemoryUsageCustom {
if self.sharedInstance == nil {
self.sharedInstance = MemoryUsageCustom()
}
return self.sharedInstance
}
private init() {
self.configureDisplayLink()
}
func startMemoryMonitor() {
if self.state == .started {
return
}
self.state = .started
self.start()
}
func stopMemoryMonitor() {
self.state = .paused
self.pause()
}
//--------------------------------------------------------------------------------
//MARK:- Display Link
//--------------------------------------------------------------------------------
func configureDisplayLink() {
self.displayLink = CADisplayLink(target: self, selector: #selector(displayLinkAction(displayLink:)))
self.displayLink.isPaused = true
self.displayLink?.add(to: .current, forMode: .common)
}
private func start() {
self.displayLink?.isPaused = false
}
/// Pauses performance monitoring.
private func pause() {
self.displayLink?.isPaused = true
}
@objc func displayLinkAction(displayLink: CADisplayLink) {
let memoryUsage = self.memoryUsage()
let bytesInMegabyte = 1024.0 * 1024.0
let usedMemory = Double(memoryUsage.used) / bytesInMegabyte
let totalMemory = Double(memoryUsage.total) / bytesInMegabyte
let memory = String(format: "%.1f of %.0f MB used", usedMemory, totalMemory)
// self.memoryString = memory
subject.send(memory)
}
func memoryUsage() -> (used: UInt64, total: UInt64) {
var taskInfo = task_vm_info_data_t()
var count = mach_msg_type_number_t(MemoryLayout<task_vm_info>.size) / 4
let result: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) {
$0.withMemoryRebound(to: integer_t.self, capacity: 1) {
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), $0, &count)
}
}
var used: UInt64 = 0
if result == KERN_SUCCESS {
used = UInt64(taskInfo.phys_footprint)
}
let total = ProcessInfo.processInfo.physicalMemory
return (used, total)
}
}
<代码>导入基础
进口联合收割机
枚举内存监视器状态{
案件开始
案件暂停
}
类内存自定义{
私有变量显示链接:CADisplayLink!
var state=MemoryMonitorState.paused
let subject=PassthroughSubject()
私有静态变量sharedInstance:MemoryUsageCustom!
公共类func shared()->memoryUsage自定义{
如果self.sharedInstance==nil{
self.sharedInstance=MemoryUsageCustom()
}
返回自我共享状态
}
私有init(){
self.configureDisplayLink()
}
func startMemoryMonitor(){
如果self.state==.started{
返回
}
self.state=.started
self.start()
}
func stopMemoryMonitor(){
self.state=.paused
self.pause()
}
//--------------------------------------------------------------------------------
//标记:-显示链接
//--------------------------------------------------------------------------------
func configureDisplayLink(){
self.displayLink=CADisplayLink(目标:self,选择器:#选择器(displayLinkAction
func GetMemory()
{
var info = mach_task_basic_info()
var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info))/4
let kerr: kern_return_t = withUnsafeMutablePointer(to: &info)
{
task_info(mach_task_self_,
task_flavor_t(MACH_TASK_BASIC_INFO),
$0.withMemoryRebound(to: Int32.self, capacity: 1) { zeroPtr in
task_info_t(zeroPtr)
},
&count)
}
if kerr == KERN_SUCCESS {
print("Memory in use (in bytes): \(info.resident_size)")
}
else {
print("Error with task_info(): " +
(String.init(validatingUTF8: mach_error_string(kerr)) ?? "unknown error"))
}
}
import Foundation
import Combine
enum MemoryMonitorState {
case started
case paused
}
class MemoryUsageCustom {
private var displayLink: CADisplayLink!
var state = MemoryMonitorState.paused
let subject = PassthroughSubject<String, Never>()
private static var sharedInstance: MemoryUsageCustom!
public class func shared() -> MemoryUsageCustom {
if self.sharedInstance == nil {
self.sharedInstance = MemoryUsageCustom()
}
return self.sharedInstance
}
private init() {
self.configureDisplayLink()
}
func startMemoryMonitor() {
if self.state == .started {
return
}
self.state = .started
self.start()
}
func stopMemoryMonitor() {
self.state = .paused
self.pause()
}
//--------------------------------------------------------------------------------
//MARK:- Display Link
//--------------------------------------------------------------------------------
func configureDisplayLink() {
self.displayLink = CADisplayLink(target: self, selector: #selector(displayLinkAction(displayLink:)))
self.displayLink.isPaused = true
self.displayLink?.add(to: .current, forMode: .common)
}
private func start() {
self.displayLink?.isPaused = false
}
/// Pauses performance monitoring.
private func pause() {
self.displayLink?.isPaused = true
}
@objc func displayLinkAction(displayLink: CADisplayLink) {
let memoryUsage = self.memoryUsage()
let bytesInMegabyte = 1024.0 * 1024.0
let usedMemory = Double(memoryUsage.used) / bytesInMegabyte
let totalMemory = Double(memoryUsage.total) / bytesInMegabyte
let memory = String(format: "%.1f of %.0f MB used", usedMemory, totalMemory)
// self.memoryString = memory
subject.send(memory)
}
func memoryUsage() -> (used: UInt64, total: UInt64) {
var taskInfo = task_vm_info_data_t()
var count = mach_msg_type_number_t(MemoryLayout<task_vm_info>.size) / 4
let result: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) {
$0.withMemoryRebound(to: integer_t.self, capacity: 1) {
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), $0, &count)
}
}
var used: UInt64 = 0
if result == KERN_SUCCESS {
used = UInt64(taskInfo.phys_footprint)
}
let total = ProcessInfo.processInfo.physicalMemory
return (used, total)
}
}
//Start Monitoring
MemoryUsageCustom.shared().startMemoryMonitor()
var storage = Set<AnyCancellable>()
MemoryUsageCustom.shared().subject.sink {[weak self] (string) in
print(string)
}.store(in: &storage)
func reportMemory() {
var taskInfo = task_vm_info_data_t()
var count = mach_msg_type_number_t(MemoryLayout<task_vm_info>.size) / 4
let result: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) {
$0.withMemoryRebound(to: integer_t.self, capacity: 1) {
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), $0, &count)
}
}
let usedMb = Float(taskInfo.phys_footprint) / 1048576.0
let totalMb = Float(ProcessInfo.processInfo.physicalMemory) / 1048576.0
result != KERN_SUCCESS ? print("Memory used: ? of \(totalMb)") : print("Memory used: \(usedMb) of \(totalMb)")
}