Когда я создаю сигнал и ввожу его в область действия функции, его эффективное количество удержания равно 0 на Cocoa условные обозначения:
RACSignal *signal = [self createSignal];
Когда я подписываюсь на сигнал, он сохраняет подписчика и возвращает одноразовый ресурс, который в соответствии с соглашениями Cocoa также имеет значение удержания нуля.
RACDisposable *disposable = [signal subscribeCompleted:^ {
doSomethingPossiblyInvolving(self);
}];
В большинстве случаев абонент будет закрываться и ссылаться на self
или на его ivars или какую-либо другую часть охватывающей области. Поэтому, когда вы подписываетесь на сигнал, сигнал имеет ссылку на подписчика, и у подписчика есть ссылка на вас. И одноразовое, которое вы получаете взамен, имеет ссылку на сигнал.
disposable -> signal -> subscriber -> calling scope
Предположим, что вы держитесь за это одноразовое устройство, чтобы в какой-то момент отменить подписку (например, если сигнал извлекает данные из веб-службы, и пользователь переходит от экрана, отменяя ее намерение просматривать данные, являющиеся извлекаться).
self.disposeToCancelWebRequest = disposable;
В этот момент мы имеем круглую ссылку:
calling scope -> disposable -> signal -> subscriber -> calling scope
Ответственность за то, чтобы цикл был нарушен при отмене запроса или после завершения запроса.
[self.disposeToCancelWebRequest dispose]
self.disposeToCancelWebRequest = nil;
Обратите внимание, что вы не можете сделать это, когда self
освобождается, потому что этого никогда не произойдет из-за цикла сохранения! Что-то также кажется подозрительным в нарушении цикла удержания во время обратного вызова подписчику, поскольку сигнал может быть удален из-за того, что его реализация все еще находится в стеке вызовов.
Я также замечаю, что реализация сохраняет глобальный список активных сигналов (с момента, когда я изначально задаю этот вопрос).
Как я могу думать о праве собственности при использовании RAC?