Ios NSObject(RACKVOWrapper)rac_observeKeyPath:选项:观察者:块:EXC_坏访问崩溃

Ios NSObject(RACKVOWrapper)rac_observeKeyPath:选项:观察者:块:EXC_坏访问崩溃,ios,uicollectionview,reactive-cocoa,Ios,Uicollectionview,Reactive Cocoa,我正在使用ReactiveCocoa使UICollectionView与消息列表保持最新。我的模型收到新消息后,尝试更新集合视图时发生崩溃 这是我的视图模型,它通过套接字客户端的委托调用获取更新 @interface ConversationViewModel : NSObject @property (nonatomic, strong) NSMutableArray *messages; - (RACSignal *)rac_signalForMessageReceived; @end

我正在使用ReactiveCocoa使UICollectionView与消息列表保持最新。我的模型收到新消息后,尝试更新集合视图时发生崩溃

这是我的视图模型,它通过套接字客户端的委托调用获取更新

@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;
}
下面是控制器如何使用它

- (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;
}
最后,这里是我如何在细胞内进行结合

- (void)awakeFromNib {
    RAC(self.messageLabel, text) = RACObserve(self, message.message);
    RAC(self.nameLabel, text) = RACObserve(self, message.name);
}
一旦集合视图重新加载,我就会在rac_observeKeyPath:options:observer:block:中得到一个异常。在屏幕截图中可以看到堆栈。


有人知道为什么会出现异常吗?还是更好的方法来处理在ConversationViewModel中接收消息?

我找到了异常崩溃的原因。将消息对象设置为使用NSString属性的属性类型assign。它需要复制。花了很长时间才找到那个

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