Como implementar um mecanismo de bloqueio reentrante no objetivo-c através do GCD?

Eu tenho uma classe object-c com alguns métodos, que usam uma fila GCD para garantir que os acessos simultâneos a um recurso ocorram em série (maneira padrão de fazer isso).

Alguns desses métodos precisam chamar outros métodos da mesma classe. Portanto, o mecanismo de bloqueio precisa ser reentrante. Existe uma maneira padrão de fazer isso?

No início, eu tinha cada um desses métodos de uso

dispatch_sync(my_queue, ^{

   // Critical section

});

para sincronizar acessos. Como você sabe, quando um desses métodos chama outro método, um deadlock acontece porque a chamada dispatch_sync pára a execução atual até que outro bloco seja executado, o que não pode ser executado também, porque a execução na fila é interrompida. Para resolver isso, eu usei, e. este método:

- (void) executeOnQueueSync:(dispatch_queue_t)queue : (void (^)(void))theBlock {
    if (dispatch_get_current_queue() == queue) {
        theBlock();
    } else {
        dispatch_sync(queue, theBlock);
    }
}

E em cada um dos meus métodos, eu uso

[self executeOnQueueSync:my_queue : ^{

   // Critical section

}];

Eu não gosto desta solução, porque para cada bloco com um tipo de retorno diferente, eu preciso escrever outro método. Além disso, esse problema parece muito comum para mim e eu acho que deveria existir uma solução padrão melhor para isso.

questionAnswers(1)

yourAnswerToTheQuestion