Я сделал эти две коммунальные funcions:ARC поведение в рекурсивном блоке
+ (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];
}
Идея заключается в том, что вы могли бы назвать:
[самостоятельной доставки: блок afterDelay: задержка]; - получить блок выполняется после определенного времени
и
[самостоятельная доставка: блока интервальный: задержки]; - получить блок выполняется периодически
Хорошо, теперь, если я позвоню отправки: интервальная:, как она есть, она будет создавать ошибку во время выполнения, потому что, когда программа пытается выполнить строку в B величины от _f будет nil; и это, в свою очередь, происходит потому, что _f имеет ссылку на значение _f по адресу A.
Это может быть исправлен, если я изменю к:
__block void (^_f)() = nil;
и с этим я делаю сильную ссылку на _f, поэтому, когда код достигает B Значения _f - это окончательное значение, присвоенное ему. Проблема заключается в том, что я увлекаюсь циклом удержания.
Наконец, я могу изменить быть:
__block void (^_f)() __weak = nil;
и должны заботиться обоих вопросов, однако я обнаружил, что, когда код достигает B Значение _f снова nil, потому что в момент его оценки _f уже освобожден.
У меня есть несколько вопросов:
- На последнем сценарии, почему _f получить освобождаться? Как сообщить ARC о сохранении блока, по крайней мере, до следующего диспетчерского вызова?
- Каким будет лучший (и ARC-совместимый) способ записи этих функций?
Спасибо за ваше время.
Просто обратите внимание, что НОД имеет тип для 'пустоте (^) (ничтожной)' - 'dispatch_block_t'. –
Спасибо, записал его – almosnow