Вопрос

I just stumbled across an odd bug in an enumerator I wrote:

// 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;
        }
    }
}

The first use of enumerateEntitiesInCategory:usingBlock: works fine. Eventually the caller finds the entity it was searching for and sets the *stop parameter to YES.

The next use of enumerateEntitiesInCategory:usingBlock: immediately exits after the first iteration. Upon closer inspection stop is now initialized to YES as soon as a previous iteration has set the *stop parameter to YES. I have to purposefully initialize the stop variable with NO to fix this.

How can this be? I know that the address of the stop variable (perhaps by chance) may have remained the same across invocations which would explain the "old" value to be there. But I was under the impression that ARC ensures uninitialized types are set to 0 respectively nil, so shouldn't it set the BOOL to NO every time the function is invoked?

Interestingly, if I use __block BOOL stop; the stop variable is always initialized to YES according to the debugger, even during the first time (again, probably by chance depending on whatever uninitialized value was at that address).

This seems to indicate that I may be wrongly assuming that uninitialized variables are zero-ed and ARC - perhaps ARC really only cares about initializing object types with nil but doesn't care about integral types? Or is this only true for ivars but not local variables?

Это было полезно?

Решение

Only pointers to Objective-C objects are initialized to nil with ARC (and all instance variables of an object), but not local variables in general. So you have to initialize the boolean variable with

BOOL stop = NO;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top