在 Swift 中访问 Objective-C 指针 [英] Accessing Objective-C Pointers in Swift

查看:62
本文介绍了在 Swift 中访问 Objective-C 指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have this Objective-C Code fragment, which I want to express in 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 后面的内存.我试过这个片段:

The first thing I´m not sure about: Who allocates the memory behind the windowListPointer. I tried with this fragment:

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

但这甚至不能编译:它抱怨,windowListPointer 没有初始化.我可以创建什么对象,让 WindowListPointer 指向?

But that does not even compile: It complains, the windowListPointer is not initialised. What Object I could create, to let the WindowListPointer point to?

推荐答案

如果你传递一个 UnsafeMutablePointer> 作为最后一个AXUIElementCopyAttributeValue() 的参数,那么你必须通过分配(并最终释放)内存来初始化它:

If you pass an UnsafeMutablePointer<Optional<AnyObject>> as the last argument to AXUIElementCopyAttributeValue() then you must initialize it by allocating (and ultimately releasing) memory:

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 变量的地址使用 &.然后有条件地将接收到的对象强制转换为预期类型,在本例中为AXUIElement 数组:

It is easier to pass the address of an Optional<AnyObject> variable with &. Then conditionally cast the received object to the expected type, in this case an array of 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` ...
    }
}

<小时>

可以定义一个通用的效用函数来封装所有演员:


One could define a generic utility function which encapsulates all the casting:

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) {

            // ...
        }
    }
}

这篇关于在 Swift 中访问 Objective-C 指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆