1

ОК, вот код.Объектив-C Блок: возвращает переменную __block из блока внутри

NSObject* (^executableBlock)(void) = ^NSObject*() { 
    __block NSObject *refObj = nil; 

    [Utility performAction:^() { 
     if (conditionA) 
       refObj = fooA; 
     else 
       refObj = fooB; 
    }; 

    return refObj; 
}; 

NSObject *result = executableBlock(); // result is nil 

После выполнения executableBlock, результат равен нулю и performAction блок не будет выполняться немедленно и возвращается мое предполагаемое значение.

Я знаю, что блок executeAction выполняется в другом потоке и использует общий указатель nil refObj. См. Working with Blocks.

Вот мой сквозной, если я использую GCD для вызова блока performAction и жду его завершения, как его переписать? Благодаря!

ответ

0

С помощью семафора вы можете подождать, пока блок не будет выполнен.
Но блок завершения может быть подходящим в вашем случае, я думаю.

NSObject* (^executableBlock)(void) = ^NSObject*() { 
    __block NSObject *refObj = nil; 

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

    [self performAction:^() { 
     if (conditionA) 
      refObj = fooA; 
     else 
      refObj = fooB; 

     dispatch_semaphore_signal(semaphore); 
    }]; 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    return refObj; 
}; 
+0

Спасибо за ваши советы, я только что нашел ответ после поиска ключевых слов ** dispatch_semaphore_create **. Ссылка: http://stackoverflow.com/a/4326754/1677041 – Itachi

0

Я хотел бы, учитывая следующее реструктурировать:

__block NSObject * result; 
    void (^executableBlock)(NSObject *) = ^void (NSObject * obj) 
    { 
     [self performAnActionWithBlock:^(BOOL success) 
     { 
      if (success) { 
       result = obj; 
       NSLog(@"results: %@", result); 
      }else{ 
       result = nil; 
      } 

     }]; 
    }; 
    executableBlock(@"Hello"); 


//where: 
-(void)performAnActionWithBlock:(void(^)(BOOL))block{ 
    block(YES); 
} 

Затем вы должны быть в состоянии назвать result из других стран

+0

Я так не думаю, это вызовет неожиданное поведение. Я думаю, вы просто хотите поделиться указателем obj между блоками/потоками. Если executeAnActionWithBlock является асинхронным и не вызывался в фоновом потоке, прежде чем я использовал указатель obj в основном потоке, значит, результат может быть нулевым. – Itachi

+0

То же самое с @ user3087154, думаю. – Itachi

0
void (^executableBlock)(NSObject*) = ^(NSObject *arg) { 

[Utility performAction:^(NSObject *arg) { 
    if (conditionA) 
      arg = fooA; 
    else 
      arg = fooB; 
}]; 

};

__block NSObject * result = nil;

executableBlock (result); // результат будет изменен в блоке

+0

Пожалуйста, добавьте более подробную информацию о вашем ответе и почему этот ответ работает. – Mehraban

Смежные вопросы