我最近发现像NSMapTable
和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...
编译器不喜欢最后一行。错误:
选择器元素类型'段*' (又名' struct Segment *')不是有效对象
那么,我需要这样做吗?
for (int i=0, len=segments.count; i<len; i++) {
Segment *seg = [segments pointerAtIndex:i];
...
那不是世界末日,但我只是想确定一下。
答案 0 :(得分:4)
(这可能更符合理论上的兴趣。)
NSPointerArray
符合NSFastEnumeration
协议,它只是。{
for (id object in collection)
语言构造,不能与任意指针一起使用
不是Objective-C指针。
但是你可以通过调用NSFastEnumeration
从数组中获得一大堆指针
方法countByEnumeratingWithState:objects:count:
直接。这有点棘手,因为
该方法无需填充提供的缓冲区(如下所述:How for in loop works internally - 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);
}
因此,这无助于使代码更简单,您可能希望坚持使用 你的显式循环。
但是对于大型数组,它可能会提高性能,因为指针是&#34;取出的&#34; 分别从数组而不是每个指针分批。
答案 1 :(得分:1)
for(... in ...)语法在这种情况下不起作用,因为Segment是结构,而不是Objective C对象。你的第二个for循环应该可以工作。