Question

I am using ReactiveCocoa to keep a UICollectionView up to date with a list of messages. I am having a crash when trying to update my collection view after my model receives new messages.

Here is my view model, that gets updates via a delegate call from a socket client.

@interface ConversationViewModel : NSObject

@property (nonatomic, strong) NSMutableArray *messages;

- (RACSignal *)rac_signalForMessageReceived;

@end

@implementation ConversationViewModel
....
- (void)client:(PSClient *)theClient didReceiveMessage:(PSMessage *)aMessage {
    [self.messages addObject:aMessage];
    [_messageReceivedSubscriber sendNext:nil]; 
}
....
- (RACSignal *)rac_signalForMessageReceived {
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        self.messageReceivedSubscriber = subscriber;
        return [RACDisposable disposableWithBlock:^{
            self.messageReceivedSubscriber = nil;
            // Do Nothing
        }];
    }];

    [signal setName:@"rac_signalForMessageReceived"];

    return signal;
}

And the message object is

@interface Message : NSObject

@property (nonatomic, assign) NSString *message;
@property (nonatomic, assign) NSString *name;

@end

And here is how the controller uses it.

- (void)viewDidLoad
    [super viewDidLoad];

    [self.conversationViewModel.rac_signalForMessageReceived subscribeNext:^(PSMessage *message) {
        [self.collectionView reloadData];
    }];

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [self.conversationViewModel.messages count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    PSConversationMessageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"conversationCell" forIndexPath:indexPath];

    [cell setMessage:self.conversationViewModel.messages[indexPath.row]];

    return cell;
}

And finally, here is how I am doing the binding inside the cell.

- (void)awakeFromNib {
    RAC(self.messageLabel, text) = RACObserve(self, message.message);
    RAC(self.nameLabel, text) = RACObserve(self, message.name);
}

As soon as the collection view reloads, I get an exception in rac_observeKeyPath:options:observer:block:. The stack is seen below in the screen shot. enter image description here

Does anyone know why this is causing an exception? Or a better way to handle receiving the message in the ConversationViewModel?

Was it helpful?

Solution

I found the reason for the unusual crash. My message object as using a property type of assign for NSString properties. It needed to be copy. Spent way to long tracking that one down.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top