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?
La solution
Autres conseils
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)]];
}