The problem was that I did not call [subscriber setCompleted]
to terminate the subscription.
Signal is already bound to key path
-
27-06-2023 - |
Question
I'm quite new to RAC and run into the following issue.
I bind a NSArray property of object to a signal that fetches some json payload from a webservice like this:
- (void)updateRandomUserData
{
RAC(self, users) = [[[self fetchRandomUserData] map:^(NSDictionary *json) {
NSMutableArray *randomUsers = [NSMutableArray array];
for (NSDictionary *dict in json[@"data"]) {
BKRandomUser *randomUser = [MTLJSONAdapter modelOfClass:[BKRandomUser class] fromJSONDictionary:dict error:nil];
[randomUsers addObject:randomUser];
}
return randomUsers;
}] catch:^(NSError *error) {
return [RACSignal return:@[]];
}];
}
I see this is working as intented when I call that from the viewDidLoad of the proper view controller:
[[[RACObserve(self.randomUserManager, users) deliverOn:RACScheduler.mainThreadScheduler] filter:^BOOL(NSArray *users) {
return users.count > 0;
}] subscribeNext:^(NSArray *newUsers) {
@strongify(self);
self.loggedOutDataSource.items = newUsers;
if (self.refreshControl.refreshing) {
[self.refreshControl endRefreshing];
}
[self.tableView reloadData];
}];
[self.randomUserManager updateRandomUserData];
However when I want to call that [self.randomUserManager reloadManager]
at a later point during the view controller's lifecycle I get a crash saying:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Signal name: [[[+createSignal:] -doError:] -map:] -catch: is already bound to key path "users" on object , adding signal name: [[[+createSignal:] -doError:] -map:] -catch: is undefined behavior'
I assume the problem is that when calling [self.randomUserManager updateRandomUserData]
it's trying to bind the NSArray property again.
So I guess the question is how can I avoid binding the property several times but still be able to use the signal that was created to call the method?
Solution
OTHER TIPS
try to unsubscribe before calling selector:
- (void)updateRandomUserData
{
RAC(self, users) = [[[[self fetchRandomUserData] map:^(NSDictionary *json) {
NSMutableArray *randomUsers = [NSMutableArray array];
for (NSDictionary *dict in json[@"data"]) {
BKRandomUser *randomUser = [MTLJSONAdapter modelOfClass:[BKRandomUser class] fromJSONDictionary:dict error:nil];
[randomUsers addObject:randomUser];
}
return randomUsers;
}] catch:^(NSError *error) {
return [RACSignal return:@[]];
}] takeUntil:[self rac_signalForSelector:@selector(updateRandomUserData)]];
}