Você pode dizer o que há de errado com esse método?
- (BOOL)doSomethingWithDictionary:(NSDictionary *)dictionary error:(NSError **)error
{
__block BOOL result = YES;
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if (![self doSomethingWithObject:key andObject:obj error:error]) {
result = NO;
*stop = YES;
}
}];
return result;
}
Se doSomethingWithObject: andObject: error: retornar um erro, o programa irá falhar em segfault quando o erro retornado for acessado pelo chamador.
Por quê? Como o erro é retornado por meio de um ponteiro de liberação automática, um objeto de erro retornado deve ser retido dentro do escopo de liberação automática atual. Parece que não fizemos isso aqui, mas acontece que enumerateKeysAndObjectsUsingBlock: (no OS X 10.7, pelo menos) configura um pool de autorelease próprio. Quando nosso método retornar, qualquer erro retornado terá sido desalocado.
Tenha cuidado ao retornar por write-back de dentro de um bloco. Você não sabe se o bloco será chamado de dentro de um novo pool de autorelease. Se é ou não, pode até variar entre os lançamentos do sistema operacional.
Este método deve usar enumeração rápida ou numeradores NSE para enumerar no dicionário. Ou pode garantir que o erro retornado seja retido imediatamente, declarando o argumento do ponteiro NSError * __ strong *.