将 CFArrayRef 转换为 NSArray 时崩溃
这很好:
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"%@", (__bridge NSArray *)windowList);
这会导致 EXC_BAD_ACCESS:
CFArrayRef windowIDList = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"Array %@", (__bridge NSArray*) windowIDList);
This is fine:
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"%@", (__bridge NSArray *)windowList);
This causes EXC_BAD_ACCESS:
CFArrayRef windowIDList = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"Array %@", (__bridge NSArray*) windowIDList);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
来自文档 NSArray:
所以问题肯定出在调用的两个方法上。同样,从文档中,
CGWindowListCopyWindowInfo
有返回值:并且
CGWindowListCreate
有返回值:当您调用 NSLog(@"%@",array); 时,消息
description
会发送到数组中的每个对象。浮点数、BOOL 和整数不响应此消息。例如,您将收到错误,但如果使用
int
调用,错误就会消失:对于您的情况,
CGWindowListCreate
返回一个CGWindowID< 数组/code> 值,这些是 32 位无符号整数。因此,它们不会响应
%@
,但会响应%u
。因此,修复方法是使用%u
手动打印数组。From the documentation on
NSArray
:So the problem must be with the two methods being called. Again, from the documentation,
CGWindowListCopyWindowInfo
has return value:and
CGWindowListCreate
has return value:When you call
NSLog(@"%@",array);
, the messagedescription
is sent to each object in the array. Floats, BOOLs and ints do not respond to this message. For example, you will get an error forbut the error goes away if you use the
int
call:For your case,
CGWindowListCreate
is returning an array ofCGWindowID
values, and these are 32 bit unsigned integers. Therefore they do no respond to%@
, but will respond to%u
. Hence the fix is to print the array manually using%u
.创建为
NSArray
s 只能包含类似于 Objective-C 对象的元素。创建为
CFArray
的数组s 可以包含任何内容,如果您传递适当的CFArrayCallBacks
到CFArrayCreate
。CGWindowListCreate
正在创建一个CFArray
,并用不像对象的东西填充它,但CGWindowListCreate
正在使用CFArrayCallbacks 不关心这个。
当您尝试使用
%@
格式说明符打印此CFArray
时,NSLog
会发送一个 Objective-C-description
消息到数组。CFArray
通过向其每个元素发送一条 Objective-Cdescription
消息来处理此问题。不幸的是,它的元素不是对象,因此不可能向它们发送 Objective-C 消息。因此崩溃了。请尝试以下操作:
CFCopyDescription
函数对数组的每个元素使用CFArrayCallbacks
函数之一,而不是尝试向每个元素发送一条 Objective-C 消息。回调知道如何处理数组元素,因此它可以正常工作。我在测试程序中得到以下输出:Arrays created as
NSArray
s can only contain elements that act like Objective-C objects.Arrays created as
CFArray
s can contain anything, if you pass the appropriateCFArrayCallBacks
toCFArrayCreate
.CGWindowListCreate
is creating aCFArray
, and filling it with things that don't act like objects, butCGWindowListCreate
is usingCFArrayCallbacks
that don't care about that.When you try to print this
CFArray
with the%@
format specifier,NSLog
sends an Objective-C-description
message to the array. TheCFArray
handles this by sending an Objective-Cdescription
message to each of its elements. Unfortunately, its elements are not objects and so it's impossible to sending Objective-C messages to them. Thus the crash.Try this instead:
The
CFCopyDescription
function uses one of theCFArrayCallbacks
functions on each element of the array, instead of trying to send an Objective-C message to each one. The callback knows how to handle the array element, so it works fine. I get this output in my test program: