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.