将CFArrayRef强制转换为NSArray时崩溃

ron*_*n_k 6 xcode cocoa objective-c quartz-graphics

这可以:

CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"%@", (__bridge NSArray *)windowList);
Run Code Online (Sandbox Code Playgroud)

这会导致EXC_BAD_ACCESS:

CFArrayRef windowIDList = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"Array %@", (__bridge NSArray*) windowIDList);
Run Code Online (Sandbox Code Playgroud)

rob*_*off 8

作为NSArrays 创建的数组只能包含像Objective-C对象一样的元素.

创建为CFArrays的数组可以包含任何内容,如果您传递适当CFArrayCallBacksCFArrayCreate.

CGWindowListCreate正在创建一个CFArray,并用不像对象的东西填充它,但CGWindowListCreate正在使用CFArrayCallbacks它不关心它.

当您尝试CFArray使用%@格式说明符打印它时,NSLog将Objective-C -description消息发送到该数组.在CFArray通过发送一个Objective-C处理此description消息发送到它的每个元素.不幸的是,它的元素不是对象,所以不可能向它们发送Objective-C消息.因此崩溃.

试试这个:

CFStringRef description = CFCopyDescription(windowIDList);
NSLog(@"Array %@", description);
CFRelease(description);
Run Code Online (Sandbox Code Playgroud)

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>
)}
Run Code Online (Sandbox Code Playgroud)