2015-11-20 2 views
2

В моем классе есть некоторые значения, которые могут быть обнаружены другой частью приложения. Эти значения могут быть прочитаны и записаны в базу данных.ReactiveCocoa: релиз RACSignal, когда никто не подписывается

У меня есть коллекция, которая сохраняет некоторые RACSubjects.

Когда объект нужно наблюдать значение V1, я создать RACSignal для этого, назовите его S1, а затем, если какой-либо другой объект, также заинтересован в V1, я дам ему V1 тоже, так что, когда S1 изменен, я могу позвонить [RACSubject sendNext:], чтобы уведомить интересующие его объекты.

Но есть проблема, я не знаю, когда выпустить S1, так как я не знаю, как получить уведомление, если нет объекта, подписавшегося на S1.

Есть ли способ сделать это?

ответ

-1

Я нашел идею для вас :)

@property (nonatomic,assign) NSInteger countOfSubscribers = 0; 

в коде

RACSignal *s; // here is your target signal 

    [[s rac_signalForSelector:@selector(subscribeNext:)] 
    subscribeNext:^(id x) { 
     self.countOfSubscribers++; 
    }]; 


    [[[s rac_signalForSelector:@selector(subscribeNext:)] rac_willDeallocSignal] 
    subscribeNext:^(id x) { 
     self.countOfSubscribers--; 
    }]; 

Основная идея заключается в том, чтобы подписаться на «subscribeNext:» метод, и когда оригинальный абонент будет удален - rac_willDeallocSignal будет вызывать.

Это не полностью проверенный фрагмент, но я надеюсь, что это поможет вам найти правильное направление.

+0

извините, но это не работает – CarmeloS

+0

Почему downvote? это просто предложение, как управлять количеством подписчиков – Doro

1

Я мысленно перефразирование часть вашего вопроса на следующие (мои изменения Курсив), потому что я думаю, что оригинальная фразировка были некоторые опечатки:

Когда объект нужно наблюдать значение V1, я будет создавать RACSubject для него, назовите его S1, а затем, если какой-либо другой объект, также заинтересован в V1, я дам ему S1 тоже, так что, когда V1 изменились, я могу назвать [RACSubject sendNext:] уведомлять объекты, которые его интересуют.

Если это неправильная интерпретация, проигнорируйте этот ответ.


Если вы явно не сохраняя сигнал себя, ReactiveCocoa will automatically reclaim it when it runs out of subscribers. Соответствующая выдержка:

  1. Созданный сигнал автоматически добавляется к глобальному набору активных сигналов.
  2. Сигнал будет ждать один проход основного цикла запуска, а затем удаляется из активного набора, если у него нет подписчиков. Если бы сигнал не был каким-то образом сохранен, он бы снял с этого момента.
  3. Если что-то подписалось в этой итерации цикла запуска, сигнал остается в наборе.
  4. Позже, когда все подписчики исчезли, шаг 2 снова запускается.

Но есть одна проблема: это не относится к RACSubject с. Они не добавляются к глобальному набору активных сигналов.

Однако, есть ... обходной способ, который можно применить, чтобы получить это хорошее поведение при автоматическом сохранении.

RACSignal *autoretainedSignal = [subject map:^(id x) { return x; }] 

Пока вы подписываетесь только autoretainedSignal, не нижележащего RACSubject, вы можете воспользоваться автоматическим сохранить поведение, что нормальные сигналы получить.

Итак, как вы держитесь за него, не сохраняя его? Если у вас есть только один сигнал, который вам интересен при кешировании/совместном использовании, вы можете просто сохранить его в слабом качестве. Если есть несколько свойств, которые вы динамически управляете, NSMapTable со слабым хранилищем - ваш друг.

Вам необходимо удержать как основной объект (чтобы вы могли отправлять события на нем), так и полученный сигнал (так что вы можете предоставить его подписчикам) слабо. Пока у получаемого сигнала есть подписчики, он сохранит свой основной объект в живых, и как только у него закончится подписчики, он и его субъект будут освобождены.

Смежные вопросы