Skip to content

Instantly share code, notes, and snippets.

@timothycosta
Last active January 27, 2016 01:19
Show Gist options
  • Save timothycosta/829df1ae35deeb93eaed to your computer and use it in GitHub Desktop.
Save timothycosta/829df1ae35deeb93eaed to your computer and use it in GitHub Desktop.
Cause Realm to crash when deleting an observed object during observeValueForKeyPath:
//
// ViewController.m
// RealmKVOCrash
//
// Created by Timothy Costa on 1/19/16.
// Copyright © 2016 Timothy Costa. All rights reserved.
//
#import "ViewController.h"
#import "UserProfile.h"
static NSString *UserProfileLanguageContext = @"UserProfileLanguageContext";
@interface ViewController ()
@property (nonatomic, strong) UserProfile *profile;
@property (nonatomic, strong) UILabel *label;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
RLMRealm *realm = [RLMRealm defaultRealm];
UserProfile *profile = [[UserProfile alloc] init];
profile.language = @"en";
profile.userId = 1234;
[realm beginWriteTransaction];
[realm addOrUpdateObject:profile];
[realm commitWriteTransaction];
[self updateProfile];
self.label = [[UILabel alloc] init];
self.label.text = @"Bob";
// [self.label addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];
}
- (IBAction)changeLanguage:(id)sender {
[self.profile.realm beginWriteTransaction];
self.profile.language = [self.profile.language stringByAppendingString:self.profile.language];
[self.profile.realm commitWriteTransaction];
self.label.text = self.profile.language;
}
- (void)updateProfile{
[self.profile removeObserver:self forKeyPath:@"language"];
NSInteger oldUserId = self.profile.userId;
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
if (self.profile){
[realm deleteObject:self.profile];
}
self.profile = [[UserProfile alloc] initWithValue:@{@"language" : @"en", @"userId" : @(oldUserId+1)}];
[realm addOrUpdateObject:self.profile];
[realm commitWriteTransaction];
RLMResults *results = [UserProfile allObjects];
self.profile = results.firstObject;
[self.profile addObserver:self forKeyPath:@"language" options:NSKeyValueObservingOptionNew context:&UserProfileLanguageContext];
}
- (void)updateLabel{
[self.label removeObserver:self forKeyPath:@"text"];
self.label = [[UILabel alloc] init];
self.label.text = self.profile.language;
[self.label addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
NSLog(@"Observed: %@", object);
if (object == self.label){
[self updateLabel];
} else if (object == self.profile){
[self updateProfile];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment