Bob White
Bob White

Reputation: 43

Strange __block storage variable crash

I have a problem in my code which I have distilled down to the following (silly) example

NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];

__block NSString *a = @"-1";

[array enumerateObjectsUsingBlock:^(id whoCares, NSUInteger idx, BOOL *stop) {
    a = [NSString stringWithFormat:@"%@ %d", a, idx];
    NSLog(@"%@", a);
}];

NSLog(@"%@", a);

This code works, but if I comment out the first NSLog (within the block) the code crashes. But, if I change the format string to the following

a = [NSString stringWithFormat:@"%d", idx];

then the code runs fine without the NSLog within the block.

What is going on here? I hope I am just misunderstanding something.

Upvotes: 4

Views: 433

Answers (1)

zpasternack
zpasternack

Reputation: 17898

stringWithFormat: gives you an autoreleased object, which you're not retaining. By the time the block exits and you call NSLog, a might have already been deallocated.

One solution might be to use a mutable string and append to it each time instead of reassigning.

NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];

NSMutableString *a = [NSMutableString stringWithFormat:@"-1"];

[array enumerateObjectsUsingBlock:^(id whoCares, NSUInteger idx, BOOL *stop) {
    [a appendFormat:@" %d", idx];
}];

NSLog(@"%@", a);

Upvotes: 2

Related Questions