在 Swift 中访问 Objective-C 指针 [英] Accessing Objective-C Pointers in Swift
问题描述
我有这个 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屋!