Cocoa 为什么CFSetGetValues会破坏传递给它的NSSet?

Cocoa 为什么CFSetGetValues会破坏传递给它的NSSet?,cocoa,automatic-ref-counting,core-foundation,Cocoa,Automatic Ref Counting,Core Foundation,我试图在一个NSSet实例上使用CFSetGetValues(),但它似乎正在阻塞该集的内存。使用观察点,集合实例将从objc\u assign\u strongCast\u non\u gc()写入。现在,我不知道发生了什么事 int main(int argc, const char * argv[]) { @autoreleasepool { NSSet *set = [NSSet setWithObjects:@1, @2, @3, nil]; const void

我试图在一个
NSSet
实例上使用
CFSetGetValues()
,但它似乎正在阻塞该集的内存。使用观察点,集合实例将从
objc\u assign\u strongCast\u non\u gc()
写入。现在,我不知道发生了什么事

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSSet *set = [NSSet setWithObjects:@1, @2, @3, nil];
    const void *objects = calloc(set.count, sizeof(id));
    CFSetGetValues((__bridge CFSetRef)set, &objects);
    NSLog(@"Set %@", set); // *** set has been clobbered ***
  }
  return 0;
}

这是在OS X 10.8上的,64位。在iOS模拟器中运行时,相同的代码失败。

调用
CFSetGetValues()
时,需要从
对象中删除
&
。请注意,
values
参数的类型为
const void**
,这意味着它是一个数组(*),其中每个元素都是一个任意指针(void*)。由于
对象
已经是一个数组,因此不需要使用
运算符获取其地址


如果数组是由函数分配的,那么使用
&
是有意义的,因此它的地址必须返回给被调用方。但事实并非如此,因为您负责分配阵列。

我无法在我的10.8.4版本和6.1 iOS模拟器上复制此功能。@CodaFi这让我更加困惑。所以log语句打印出了整个集合?而且,我不确定为什么
-[NSSet getObjects::
不是(公共)API
NSArray
sensorderedset
导出
-getObjects:range:
,但是
-[NSSet getObjects::
是私有的。另一种思考方式是
对象
应该是
常量id*
,而且既然
id
已经是指针,它类似于
const void**
。当我看到
**
时,我总是想传入某种形式的
&指针
,正如您所说,它适用于输出参数。现在我明白了,因为
id
是一个指针,所以表达式
calloc(set.count,sizeof(id))
不明显地导致
***
,因此获取该表达式的地址会导致
***
。是的,我也在想为什么
NSSet
没有
-getObjects:
CFSetGetValues()
当您删除操作员tho的地址时,一点也不高兴。真的太糟糕了,你必须对
void**
执行未经检查的强制转换。