2

我刚刚在我写的枚举器中偶然发现了一个奇怪的错误:

// typedef for reference
typedef void (^OGWEntityEnumerationBlock)(OGWEntity* entity, BOOL* stop);


-(void) enumerateEntitiesInCategory:(const OGWEntityCategory*)category 
                         usingBlock:(OGWEntityEnumerationBlock)block
{
    BOOL stop;
    NSArray* entitiesInCategory = [_cagetorizedEntities objectForKey:category];

    for (OGWEntity* entity in [entitiesInCategory reverseObjectEnumerator])
    {
        block(entity, &stop);

        if (stop)
        {
            break;
        }
    }
}

第一次使用enumerateEntitiesInCategory:usingBlock:效果很好。最终调用者找到它正在搜索的实体并将*stop参数设置为YES

enumerateEntitiesInCategory:usingBlock:在第一次迭代后立即退出下一次使用。仔细检查后stop,现在初始化为YES只要先前的迭代已将*stop参数设置为 YES。我必须有目的地初始化 stop 变量NO来解决这个问题。

怎么会这样?我知道停止变量的地址(可能是偶然的)在调用中可能保持不变,这可以解释“旧”值的存在。但我的印象是 ARC 确保未初始化的类型分别设置为 0 nil,所以每次调用函数时不应该将 BOOL 设置为 NO 吗?

有趣的是,如果我使用__block BOOL stop;stop 变量,则始终根据调试器初始化为 YES,即使在第一次也是如此(同样,可能偶然取决于该地址处的任何未初始化值)。

这似乎表明我可能错误地假设未初始化的变量是零变量和 ARC——也许 ARC 真的只关心用 nil 初始化对象类型而不关心整数类型?或者这仅适用于 ivars 而不是局部变量?

4

1 回答 1

6

只有指向 Objective-C 对象的指针才nil用 ARC(以及对象的所有实例变量)初始化,而不是一般的局部变量。所以你必须初始化布尔变量

BOOL stop = NO;
于 2013-10-09T15:23:01.033 回答