Search code examples
iosreactive-cocoa

Reactive Cocoa - listening for notifications & memory management


I would like to know if someone else had some issue with Reactive Cocoa listenForNotification method. I'm experiencing a retain cycle using the following code and my viewController dealloc method is never called. If I don't listen for that notification my viewController is properly dealloc'ed

HERE IS THE UPDATE FULL BLOCK OF CODE, in which I call the method to listen for notifications:

RACSignal *postSignal = [RACSignal empty];        
postSignal = [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:kNotification object:self.conversation] takeUntil:self.rac_willDeallocSignal]] bind:^RACStreamBindBlock{
        return ^RACSignal *(NSNotification *note, BOOL *stop) {
            XXStatus status = [note.userInfo[@"status"] longValue];
            if (status == XXStatusPosted) {
                *stop = YES;
                return [RACSignal empty];
            } else {
                return [RACSignal error:note.userInfo[@"error"]];
            }
        };

[[[[RACSignal merge:@[uploadSignal, postSignal]] deliverOnMain] subscribeCompleted:^{
    [self doSomethingX];
} error:^(NSError *error) {
    [self doSomethingOnFail:error];
}] autoDispose:self];

Do you know how RAC memory management works for listening notifications? Where notification center is the default notification center in the app. And the method is included in a category extension of NSObject class.

Thanks for your answer.


Solution

  • That isn't really a complete code snippet (it has unbalanced delimiters), so it's possible you've accidentally left something out that might have made it more clear. But it looks like the reason you have a retain cycle is in the very last line:

    }] autoDispose:self];
    

    That reference to self doesn't appear to be a weak reference, which means the bind block has an strong ("ownership") reference to self. If so, self will never be released, so the self.rac_willDeallocSignal never sends a value. And that means that the observer is never removed from the NSNotificationCenter.