Я сталкиваюсь со странной проблемой при попытке получить доступ к переменной __block
(изменяемый блок) из-за пределов блока, в котором она изменена. Это очень забавный пример, который я использую просто для лучшего понимания блоков в целом, но в настоящее время у меня есть контроллер с этим методом, который создает строку с содержимым NSDictionary
, который использует NSDictionary
enumerateKeysAndObjectsUsingBlock:
- (NSString*) contentsOfDictionary:(NSDictionary*)dictionary
{
__block NSString *content = @"";
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
NSString* contentToAppend = [NSString stringWithFormat:@"Object:%@ for key:%@\n", obj, key];
content = [content stringByAppendingString:contentToAppend];
NSLog(@"Content in block:\n%@", content);
}];
NSLog(@"Content out of block:\n%@", content);
return content;
}
Когда я запускаю этот метод со словарем, содержащим содержимое:
Value Key
"Queen" "card"
"Hearts" "suit"
"10" "value"
Переменная content
корректно изменяется внутри блока, и я получаю этот вывод при каждой итерации:
... Содержимое в блоке:
Object:Queen for key:card
... Содержимое в блоке:
Object:Queen for key:card
Object:Hearts for key:suit
... Содержимое в блоке:
Object:Queen for key:card
Object:Hearts for key:suit
Object:10 for key:value
Как только код выходит из блока, при доступе к строке content
выдается EXC_BAD_ACCESS
, и в одном случае запуска кажется, что он напечатал некоторую мусорную память (не может воспроизвести) ...
Что вызывает раннее освобождение этой переменной? У меня сложилось впечатление, что если дать ему определение __block
, это будет означать, что оно сохраняется при использовании внутри блока и освобождается при выходе из блока. Но переменная сохраняется и автоматически высвобождается для запуска, поскольку является строковым литералом Я ожидаю, что он не будет освобожден до тех пор, пока этот метод не выйдет в ближайшее время.