gpt4 book ai didi

arrays - Swift "Array"内存分配,加上切换显示镜像

转载 作者:行者123 更新时间:2023-11-30 10:02:27 31 4
gpt4 key购买 nike

注意:请参阅下面的修订帖子:硬件镜像

我编写了两个 Swift 函数来切换 OSX 中的显示镜像。两者都有效;它们之间的区别只是处理指针时的语法。为了方便那些有兴趣学习如何在 Swift 中切换镜像的人,我在下面包含了 Playground 文件的文本。

我的问题是关于内存分配的。这是感兴趣的部分:

切换镜像丑陋

    // allocate space for array
let displayListPtr = displayIDListPtr.alloc(Int(displayCount)) //see typealias above
// fill the list
postError(CGGetActiveDisplayList(displayCount, displayListPtr, &activeCount))

切换镜像

    // allocate space for list of displays
var displayIDList = Array<CGDirectDisplayID>(count: Int(displayCount), repeatedValue: kCGNullDirectDisplay)
// fill the list
postError(CGGetActiveDisplayList(displayCount, &displayIDList, &activeCount))

CGGetActiveDisplayList 是一个低级函数调用,它依赖于排列在连续内存位置中的数据。我有理由相信丑陋版本中的“alloc”是连续的。根据经验,“Array(...)”调用似乎也是连续的,但我可以相信它总是正确的吗(例如,如果显示器的数量增加)?这个关于 Swift 数组初始值设定项的假设是不是很糟糕?

<小时/>

这是所有代码;对于格式问题深表歉意。请注意,只应调用这两个函数之一;否则,你最终会回到起点。

//: Playground - noun: a place where people can play

import Cocoa

// apparently not defined in Swift version of SDK 10.11 (XCode 7.3.1), so add manually
let kCGNullDirectDisplay = CGDirectDisplayID(0)
let kCGDirectMainDisplay = CGMainDisplayID() // not used here, just for the record

let maxDisplays:UInt32 = 20 // not used
var onlineCount:UInt32 = 0 // not used

func postError(error : CGError){
if error != CGError.Success {
print("got an error")
}
}


// this toggles all active displays, online or not
func toggleMirroring(){
var displayCount:UInt32 = 0
var activeCount:UInt32 = 0
//var onlineCount:UInt32 = 0 //not used

//get count of active displays (by passing nil to CGGetActiveDisplayList
postError(CGGetActiveDisplayList(0, nil, &displayCount))

if displayCount < 2 { return } // no point in any mirroring functions

//***
// allocate space for list of displays
var displayIDList = Array<CGDirectDisplayID>(count: Int(displayCount), repeatedValue: kCGNullDirectDisplay)

// fill the list
postError(CGGetActiveDisplayList(displayCount, &displayIDList, &activeCount))
//***

// determine if mirroring is active
// hack to convert from boolean_t (aka UInt32) to swift's bool
let displaysMirrored = CGDisplayIsInMirrorSet(CGMainDisplayID()) != 0

// set master based on current mirroring state
// if mirroring, master = null, if not, master = main display
let master = (true == displaysMirrored) ? kCGNullDirectDisplay : CGMainDisplayID()

// start the configuration
var configRef:CGDisplayConfigRef = nil //swift 3 syntax

postError(CGBeginDisplayConfiguration(&configRef));

for i in 0..<Int(displayCount) {
let currentDisplay = CGDirectDisplayID(displayIDList[i])
if CGMainDisplayID() != currentDisplay {
CGConfigureDisplayMirrorOfDisplay(configRef, currentDisplay, master);
}
}

if (false){ // change to true in order to execute the toggle
postError(CGCompleteDisplayConfiguration (configRef,CGConfigureOption.Permanently))
}

// The first entry in the list of active displays is the main display. In case of mirroring, the first entry is the largest drawable display or, if all are the same size, the display with the greatest pixel depth.
// The "Permanently" option might not survive reboot when run from playground, but does when run in an application
}

func toggleMirroringUgly(){
// just to decrease eye strain
typealias displayIDListPtr = UnsafeMutablePointer<CGDirectDisplayID>
typealias configurationRefPtr = UnsafeMutablePointer<CGDisplayConfigRef>

//get count of active displays (by passing nil to CGGetActiveDisplayList
postError(CGGetActiveDisplayList(0, nil, &displayCount))

if displayCount < 2 { return } // no point in any mirroring functions

// ***
// allocate space for array
let displayListPtr = displayIDListPtr.alloc(Int(displayCount)) //see typealias above
// fill the list
postError(CGGetActiveDisplayList(displayCount, displayListPtr, &activeCount))
// ***

// determine if mirroring is active
// hack to convert from boolean_t (aka UInt32) to swift's bool
let displaysMirrored = CGDisplayIsInMirrorSet(CGMainDisplayID()) != 0
// set master based on current mirroring state
// if mirroring master = null, if not, master = main display
let master = (true == displaysMirrored) ? kCGNullDirectDisplay : CGMainDisplayID()

// make room for the configuration reference
let configRefPtr = configurationRefPtr.alloc(1) //see typealias above
// start the configuration
postError(CGBeginDisplayConfiguration (configRefPtr));

for i in 0..<displayCount {
let currentDisplay = CGDirectDisplayID(displayListPtr[Int(i)])
if CGMainDisplayID() != currentDisplay {
CGConfigureDisplayMirrorOfDisplay(configRefPtr[0], currentDisplay, master);
}
}

if (false){ //change to true in order to flip the mirroring
// make it happen
postError(CGCompleteDisplayConfiguration (configRefPtr[0],CGConfigureOption.Permanently));
}
// The first entry in the list of active displays is the main display. In case of mirroring, the first entry is the largest drawable display or, if all are the same size, the display with the greatest pixel depth.
// The "Permanently" option might not survive reboot when run from playground, but does when run in an application
}


toggleMirroring()

最佳答案

数组不一定使用连续存储。有一个ContiguousArray如果您愿意,可以使用该类型,但您仍然需要处理最大大小与最终调用 CGGetActiveDisplayList 后返回的实际大小之间可能存在的差异。 .

清理这个问题的一种方法可能是为数组创建一个自定义的便利初始化程序:

extension Array {

init<Size: IntegerType>(
fillingBufferOfSize maxSize: Size,
@noescape fillBuffer: (buffer: UnsafeMutablePointer<Element>, count: inout Size) throws -> ()) rethrows
{
let maxSizeAsInt = Int(maxSize.toIntMax())
let buf = UnsafeMutablePointer<Element>.alloc(maxSizeAsInt)
defer { buf.dealloc(maxSizeAsInt) }

var actualCount: Size = 0
try fillBuffer(buffer: buf, count: &actualCount)

self.init(UnsafeBufferPointer(start: buf, count: Int(actualCount.toIntMax())))
}

}

然后你可以使用Array(fillingBufferOfSize: ...) :

var maxActive: UInt32 = 0
CGGetActiveDisplayList(0, nil, &maxActive)

let displays = Array(fillingBufferOfSize: maxActive) { (buffer, count) in
CGGetActiveDisplayList(maxActive, buffer, &count)
}

关于arrays - Swift "Array"内存分配,加上切换显示镜像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37690426/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com