Я хочу установить указатель NSError из блока в проекте, используя автоматический подсчет ссылок. Далее следует упрощенная версия моего кода:
- (BOOL)frobnicateReturningError:(NSError **)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
[blockSelf doSomethingWithItem:item error:error];
}];
}
Это компилируется, но учитывая, что error
может быть изменено doSomethingWithItem
, я попытался создать локальный NSError для изменения блока, который затем будет использоваться для установки исходного error
после перечисления (которое я не показал):
- (BOOL)frobnicateReturningError:(NSError **)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
__block NSError *blockError = nil;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
[blockSelf doSomethingWithItem:item error:&blockError];
}];
}
Это не скомпилируется со следующей ошибкой:
передача адреса нелокального объекта в параметр __autoreleasing для обратной записи
Поиск этой ошибки в Google возвращает результаты только из самого исходного кода Clang.
Одно решение, которое кажется рабочим, но немного уродливым, состоит в том, чтобы иметь внутренний и внешний указатель ошибки:
- (BOOL)frobnicateReturningError:(NSError **)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
__block NSError *outerError = nil;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
NSError *innerError = nil;
[blockSelf doSomethingWithItem:item error:&innerError];
outerError = innerError;
}];
}
Как правильно установить NSError внутри блока?