Comportamento ARC dentro de um bloco recursivo

Eu fiz estas duas funções do utilitário:

+ (void)dispatch:(void (^)())f afterDelay:(float)delay {
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay*NSEC_PER_SEC)),
                    dispatch_get_main_queue(),
                    f);
  }

+ (void)dispatch:(void (^)())f withInterval:(float)delay {
    void (^_f)() = nil; // <-- A
    _f = ^{
        f();
        [self dispatch:_f afterDelay:delay]; // <-- B
    };
    [self dispatch:_f afterDelay:delay];
}

A ideia é que você seria capaz de ligar:

[auto despacho:quadra&nbsp;afterDelay:demora]; - para obter um bloco executado após um tempo específico

e

[auto despacho:quadra&nbsp;withInterval:demora]; - para obter um bloco executado periodicamente

Ok, agora, se eu ligarexpedição: withInterval:, como é, ele criará um erro em tempo de execução porque quando o programa tenta executar a linha emB&nbsp;o valor de_f&nbsp;seránada; e isso, por sua vez, acontece porque_f&nbsp;contém uma referência ao valor de_f&nbsp;aA.

Isso poderia ser corrigido se eu mudarA&nbsp;para:

__block void (^_f)() = nil;

e com isso eu estou fazendo uma forte referência a_f, então quando o código chegarB&nbsp;o valor de_f&nbsp;é o valor final que foi atribuído a ele. O problema com isso é que estou incorrendo em um ciclo de retenção.

Finalmente, posso mudarA&nbsp;ser estar:

__block void (^_f)() __weak = nil;

e essadevemos&nbsp;cuidar de ambos os problemas, no entanto, descobri que quando o código atingeB&nbsp;o valor de_f&nbsp;está de novonada&nbsp;porque, no momento em que é avaliado,_f&nbsp;já foi desalocado.

Eu tenho algumas perguntas:

No último cenário, por que_f&nbsp;ser desalocado? Como eu digo ao ARC para reter o bloco pelo menos até a próxima chamada de envio?Qual seria a melhor maneira (e compatível com ARC) de escrever essas funções?

Obrigado pelo seu tempo.