这很好:
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"%@", (__bridge NSArray *)windowList);
这会导致EXC_BAD_ACCESS:
CFArrayRef windowIDList = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"Array %@", (__bridge NSArray*) windowIDList);
答案 0 :(得分:8)
创建为NSArray
的数组只能包含与Objective-C对象相似的元素。
如果您将相应的CFArray
传递给CFArrayCallBacks
,则CFArrayCreate
创建的数组可以包含任何内容。
CGWindowListCreate
正在创建一个CFArray
,并用不像对象的东西填充它,但是CGWindowListCreate
正在使用不关心它的CFArrayCallbacks
当您尝试使用CFArray
格式说明符打印此%@
时,NSLog
会向阵列发送一条Objective-C -description
消息。 CFArray
通过向每个元素发送Objective-C description
消息来处理此问题。不幸的是,它的元素不是对象,所以不可能向它们发送Objective-C消息。因此崩溃。
请改为尝试:
CFStringRef description = CFCopyDescription(windowIDList);
NSLog(@"Array %@", description);
CFRelease(description);
CFCopyDescription
函数在数组的每个元素上使用CFArrayCallbacks
函数之一,而不是尝试向每个元素发送一个Objective-C消息。回调知道如何处理数组元素,所以它工作正常。我在测试程序中得到了这个输出:
2011-11-10 18:50:23.888 test[15156:707] <CFArray 0x1001140c0 [0x7fff7fd24ea0]>{type = mutable-small, count = 19, values = (
0 : <0x7d7>
1 : <0x2d>
2 : <0x20>
3 : <0x21>
4 : <0x1e>
5 : <0x9>
6 : <0x7a8>
7 : <0x2c>
8 : <0x2e>
9 : <0x743>
10 : <0x32>
11 : <0x85>
12 : <0x695>
13 : <0x62a>
14 : <0x62b>
15 : <0xa>
16 : <0x26>
17 : <0x18>
18 : <0x2>
)}
答案 1 :(得分:1)
来自NSArray
上的documentation:
NSArray与其核心基金会对应的“免费桥接”, CFArray参考。这意味着Core Foundation类型是什么 可以在函数或方法调用中与bridged互换 基础对象,提供将一种类型转换为另一种类型。 因此,在您看到NSArray *参数的API中,您可以 传入CFArrayRef,并在API中看到CFArrayRef 参数,您可以传入NSArray实例。这种安排也 适用于NSArray的具体子类。
所以问题必须是调用两个方法。同样,从文档中,CGWindowListCopyWindowInfo
具有返回值:
CFDictionaryRef类型的数组,每个类型都包含信息 关于当前用户会话中的一个窗口。如果没有 窗口匹配所需的标准,该函数返回一个空 阵列。如果从GUI安全性之外调用此函数 会话或没有窗口服务器正在运行时,此函数返回 NULL。
和CGWindowListCreate
有返回值:
与所需窗口对应的CGWindowID值数组。如果 没有符合所需标准的窗口,该功能 返回一个空数组。如果你从a外面调用这个函数 GUI安全会话或没有窗口服务器运行时,这个 函数返回NULL。
当您致电NSLog(@"%@",array);
时,消息description
将发送到阵列中的每个对象。 Floats,BOOL和int不响应此消息。例如,您将收到
NSLog(@"Printing 2: %@",2);
但如果您使用int
电话,则错误会消失:
NSLog(@"Printing 2: %d",2);
对于您的情况,CGWindowListCreate
返回CGWindowID
个值的数组,这些是32位无符号整数。因此,他们不回复%@
,但会回复%u
。因此,修复方法是使用%u
手动打印数组。