Второе исправление заключается в использовании __block

у установить указатель 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 из блока?

Ответы на вопрос(2)

Ваш ответ на вопрос