The use of RAC has been covered in many articles, but the NSNotificationCenter has rarely been covered. You don’t use removeObserver if you’re using RAC, but that’s not the case.

If this interface is pushed here. In viewDidLoad, listen for notifications, using RAC. Then pop back and push in… The result is that multiple observers have been added to the notification, and the previous one has been released. It seems fine, because sending messages to nil is fine, but if you have singleton access in there, or use the -> operator, as I said in the last article, it can be a serious problem. So viewDidLoad goes a couple of times, and the next time the notification fires it’s going to go a couple of blocks.

RAC listening notification is implemented as follows:

@implementation NSNotificationCenter (RACSupport)

- (RACSignal *)rac_addObserverForName:(NSString *)notificationName object:(id)object {
	@unsafeify(object);
	return[[RACSignal createSignal:^(id<RACSubscriber> subscriber) { @strongify(object);  id observer = [self addObserverForName:notificationName object:object queue:nil usingBlock:^(NSNotification *note) { [subscriber sendNext:note]; }];return [RACDisposable disposableWithBlock:^{
			[self removeObserver:observer];
		}];
	}] setNameWithFormat:@"-rac_addObserverForName: %@ object: <%@: %p>", notificationName, [object class], object];
}

@end
Copy the code

It’s subscription. SubscribeNext is a subscription. In general, how do you remove subscriptions? Must be calling the Dispose method in RACDisposable. Note that [NSNotificationCenter defaultCenter] removeObserver is invalid. Because we subscribe to RAC’s signal.

In RAC, RACDisposable was created and dispose method was not called at the appropriate time. So the following block will not go at all, removeObserver will not go at all!

[RACDisposable disposableWithBlock:^{
    [self removeObserver:observer];
}];
Copy the code

Who does it return to? In addition, NSNotificationCenter is a singleton, so its rac_willDeallocSignal must be present at the end of the program, and its implementation does not subscribe to rac_willDeallocSignal.

The only way to remove this observer is to call its Dispose method on the dealloc of the controller by using the RACDisposable to receive the returned RACSignal. But this is not worth the cost, so the controller has to hold on to the returned result. I might as well do what the system did.

RAC is still pretty powerful, but it’s not recommended when you need to listen for notifications!

If you have any different opinions, feel free to leave a comment in the comments section