4

我最近发现了像NSMapTableand这样的类NSPointerArray,它们的工作方式类似于传统的集合,但也可以让您存储弱引用或普通的旧 C 指针。不幸的是,您似乎无法使用该for...in语法来迭代非NSObject指针。例如:

typedef struct Segment {
    CGPoint bottom, top;
} Segment;
...
NSPointerArray *segments = [[NSPointerArray alloc] 
                                 initWithOptions:NSPointerFunctionsOpaqueMemory];
...
Segment *s = malloc(sizeof(Segment));
[segments addPointer: s];
...
for (Segment *s in segments) {   // nope...

编译器不喜欢最后一行。错误:

选择器元素类型“Segment *”(又名“struct Segment *”)不是有效对象

那么,我需要这样做吗?

for (int i=0, len=segments.count; i<len; i++) {
    Segment *seg = [segments pointerAtIndex:i];
    ...

那不是世界末日,但我只是想确定一下。

4

2 回答 2

4

(这可能更具理论意义。) NSPointerArray 确实符合NSFastEnumeration协议,它只是 for (id object in collection)不能与不是 Objective-C 指针的任意指针一起使用的语言结构。

NSFastEnumeration 但是您可以通过直接调用该方法从数组中获取一大堆指针countByEnumeratingWithState:objects:count:。这有点棘手,因为该方法不需要填充提供的缓冲区(如此处所述:for in loop 如何在内部工作 - Objective C - Foundation)。

这是一个如何工作的简单示例:

__unsafe_unretained id objs[10];
NSUInteger count = [segments countByEnumeratingWithState:&state
                                                 objects:objs count:10];

// Now state.itemsPtr points to an array of pointers:
for (NSUInteger i = 0; i < count; i++) {
    Segment *s = (__bridge Segment *)state.itemsPtr[i];
    NSLog(@"%p", s);
}

因此,这无助于使代码更简单,您可能希望坚持使用显式循环。

但是对于大型数组,它可能会提高性能,因为指针是从数组中分批“获取”的,而不是分别从每个指针中“获取”。

于 2014-03-24T01:04:31.777 回答
1

for (... in ...) 语法在这种情况下不起作用,因为 Segment 是一个结构,而不是 Objective C 对象。您的第二个 for 循环应该可以工作。

于 2014-03-24T00:25:21.670 回答