ObjC:局部变量似乎在函数调用中保持其值

Lea*_*s2D 2 scope enumeration objective-c objective-c-blocks automatic-ref-counting

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

// 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

第一次使用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但不适用于局部变量?

Mar*_*n R 6

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

BOOL stop = NO;
Run Code Online (Sandbox Code Playgroud)