在 Swift 中访问 Objective-C 指针

2024-03-14

我有这个 Objective-C 代码片段,我想用 Swift 表达它

CFArrayRef windowList;
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);

if ((!windowList) || CFArrayGetCount(windowList)<1)
        continue;

AXUIElementRef windowRef = (AXUIElementRef) CFArrayGetValueAtIndex( windowList, 0);
CFTypeRef role;
AXUIElementCopyAttributeValue(windowRef, kAXRoleAttribute, (CFTypeRef *)&role);         

我不确定的第一件事是:谁分配了 windowListPointer 后面的内存。 我尝试使用这个片段:

var windowListPointer : UnsafeMutablePointer<Optional<AnyObject>>
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute as CFString, windowListPointer );

但这甚至无法编译:它抱怨 windowListPointer 未初始化。 我可以创建什么对象来让 WindowListPointer 指向?


如果您通过了UnsafeMutablePointer<Optional<AnyObject>>作为最后一个 论证AXUIElementCopyAttributeValue()那么你必须 通过分配(并最终释放)内存来初始化它:

var resultPtr: UnsafeMutablePointer<Optional<AnyObject>> = UnsafeMutablePointer.allocate(capacity: 1)
resultPtr.initialize(to: nil)

let result = AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute as CFString, resultPtr)
// ...

resultPtr.deinitialize()
resultPtr.deallocate(capacity: 1)

更容易 传递地址Optional<AnyObject>多变的 和&。然后有条件地 将接收到的对象转换为预期类型,在本例中为 的数组AXUIElement:

var value: AnyObject?
let result = AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute as CFString, &value)
if result == .success, let windowList = value as? [AXUIElement] {
    // use `windowList`
}

类似地:

if let window = windowList.first {
    var value: AnyObject?
    let result = AXUIElementCopyAttributeValue(window, kAXRoleAttribute as CFString, &value)
    if result == .success, let role = value as? String {
        // use `role` ...
    }
}

人们可以定义一个通用的实用函数,它封装了 所有铸造:

func axUICopyAttributeValue<T>(of element: AXUIElement, attribute: String, as type: T.Type) -> T? {
    var value: AnyObject?
    let result = AXUIElementCopyAttributeValue(element, attribute as CFString, &value)
    if result == .success, let typedValue = value as? T {
        return typedValue
    }
    return nil
}

用法示例:

if let windowList = axUICopyAttributeValue(of: appRef, attribute: kAXWindowsAttribute, as:[AXUIElement].self) {

    for window in windowList {
        if let role = axUICopyAttributeValue(of: window, attribute: kAXRoleAttribute, as: String.self) {

            // ...
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Swift 中访问 Objective-C 指针 的相关文章

随机推荐