自动引用计数:快速枚举时出错

时间:2011-10-19 00:33:50

标签: objective-c ios ios5 automatic-ref-counting

在更新下面的代码以使用iOS 5的自动引用计数时,在尝试执行快速枚举时为“state-> itemPtr”分配缓冲区时发生错误,以便可以使用“foreach”循环。我得到的错误是“将'__autoreleasing id *'分配给'__unsafe_unretained id *'更改指针的保留/释放属性”。请参阅注释的代码行。

/*
 * @see http://cocoawithlove.com/2008/05/implementing-countbyenumeratingwithstat.html
 * @see http://www.mikeash.com/pyblog/friday-qa-2010-04-16-implementing-fast-enumeration.html
 */
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state objects: (id *)buffer count: (NSUInteger)bufferSize {
    NSUInteger arrayIndex = (NSUInteger)state->state;
    NSUInteger arraySize = [_tuples count];
    NSUInteger bufferIndex = 0;

    while ((arrayIndex < arraySize) && (bufferIndex < bufferSize)) {
        buffer[bufferIndex] = [_tuples objectAtIndex: arrayIndex];
        arrayIndex++;
        bufferIndex++;
    }

    state->state = (unsigned long)arrayIndex;
    state->itemsPtr = buffer; // Assigning '__autoreleasing id *' to '__unsafe_unretained id*' changes retain/release properties of pointer
    state->mutationsPtr = (unsigned long *)self;

    return bufferIndex;
}

此示例中的_tuples变量是NSMutableArray类型的实例变量。

如何解决此错误?

2 个答案:

答案 0 :(得分:15)

您需要将缓冲区更改为__unsafe_unretained

- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state
                                   objects: (id __unsafe_unretained *)buffer
                                     count: (NSUInteger)bufferSize

source

编辑:轻松摆脱mutationPtr中的错误:

state->mutationsPtr = &state->extra[0];

答案 1 :(得分:1)

Ziminji,

我遇到了同样的问题,这就是我遇到这个问题的方式。

我通过保持 objects参数的定义(例如,将其保持为id *)并使用void指针进行双重转换来解决它。

所以,虽然这给我带来了错误:

state->itemsPtr = (__unsafe_unretained id *)buffer  // Error

这很有效:

state->itemsPtr = (__unsafe_unretained id *)(void *)buffer  // No error

免责声明:我不是ARC专家,我不能保证这不会引起参考计数问题。但是,出现才能在我的测试中正常工作,肯定会编译而不会发出警告。

顺便说一句,我看到了这个由两部分组成的博客文章,其中涵盖了快速枚举的深度:

以及__unsafe_unretained上的此博客条目: