Zachowanie ARC w bloku rekurencyjnym

Zrobiłem te dwie funkcje użytkowe:

+ (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];
}

Chodzi o to, że będziesz mógł zadzwonić:

[samodzielna wysyłka:blok afterDelay:opóźnienie]; - aby uzyskać blok wykonany po określonym czasie

i

[samodzielna wysyłka:blok withInterval:opóźnienie]; - aby okresowo wykonać blok

Ok teraz, jeśli zadzwonięwysyłka: withInterval:tak jak jest, spowoduje błąd w czasie wykonywania, ponieważ gdy program próbuje wykonać linię wB wartość_fa będziezero; a to z kolei dzieje się, ponieważ_fa zawiera odniesienie do wartości_fa wA.

Można to naprawić, jeśli się zmienięA do:

__block void (^_f)() = nil;

i z tym się odwołuję_fa, więc kiedy kod sięgaB wartość_fa to końcowa wartość, która została mu przypisana. Problem polega na tym, że ponoszę cykl.

Wreszcie mogę się zmienićA być:

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

i topowinien zajmij się obydwoma problemami, jednak znalazłem to, gdy kod sięgaB wartość_fa jest znowuzero ponieważ w momencie oceny_fa został już zwolniony.

Mam kilka pytań:

W ostatnim scenariuszu dlaczego_fa zostać zwolnionym? Jak powiedzieć ARC, aby zachowała blok przynajmniej do następnego wywołania wysyłki?Jaki byłby najlepszy (i zgodny z ARC) sposób zapisu tych funkcji?

Dziękuję za Twój czas.

questionAnswers(2)

yourAnswerToTheQuestion