【问题标题】:realm sumOfProperty does not give most recent update领域 sumOfProperty 不提供最新更新
【发布时间】:2015-12-11 05:15:06
【问题描述】:

Realm 0.96.3 大师。

我有一个创建两个Person 记录的测试。每个人都有一个NSNumber<RLMDouble> *walkDistance 属性。

人物模型

@interface Person : RLMObject
@property NSString  *id;
@property NSString  *name;
@property NSDate    *birthdate;
@property NSNumber<RLMDouble>  *walkDistance;
@property RLMArray<Dog *><Dog> *dogs;
@end
RLM_ARRAY_TYPE(Person)

viewDidLoad

在一个表格视图中,我创建了一个RLMRealm self.database 和一个RLMResult self.persons。在viewDidLoad的主线程上:

self.bgq = dispatch_queue_create("com.salesram.bgqueu", NULL);
self.database = [self getEncryptedRealm];
self.persons = [[Person objectsInRealm:self.database withPredicate:nil]
__typeof__(self) __weak weakSelf = self;
self.token = [self.database addNotificationBlock:^(NSString * _Nonnull notification, RLMRealm * _Nonnull realm) {
    [weakSelf.tableView reloadData];
    [weakSelf calculateTotal];
}];

getEncryptedRealm 是一个标准的 Realm 创建:

    NSData *key = [NSData dataWithBytes:c length:64];
    // Open the encrypted Realm file
    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
    config.encryptionKey = key;
    NSError *error;
    RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error];
    assert(realm != nil);

    return realm;

创建数据:

我有一个函数 createData 在后台线程中创建 2 个人。另一个函数清除后台线程中的所有对象,然后添加 2 个新人。他们都使用 GCD 相同的队列。所以它们按顺序运行。 [在同一个线程上并且(编辑:它们可以在不同的线程中运行)]

- (void)createData:(int)seq
{
dispatch_async(self.bgq, ^{
    NSLog(@"start %i", seq);
    @autoreleasepool {
        RLMRealm *db = [self getEncryptedRealm];
        //[db refresh];
        [db beginWriteTransaction];
        for (int i = 0; i < 2; i++) {

            NSString *pid = [NSString stringWithFormat:@"%i", arc4random()%100];
            Person *person = [Person createOrUpdateInRealm:db withValue:@{@"id": [NSString stringWithFormat:@"%@", pid]}];
            person.name = [NSString stringWithFormat:@"Person Name # %@", pid];
            person.walkDistance = [NSNumber numberWithDouble:arc4random()%3+1];
            // omits some code of creating dogs...
        }
        [db commitWriteTransaction];

        NSLog(@"end %i", seq);
    }
});
}

清除数据库:

clearDB 将删除所有内容并在后台串行队列中重新创建所有内容。

- (IBAction)clearDB:(UIBarButtonItem *)sender
{
    dispatch_async(self.bgq, ^{
        RLMRealm *db = [self getEncryptedRealm];
        [db beginWriteTransaction];
        [db deleteAllObjects];
        [db commitWriteTransaction];
    });
    [self createData:1];
}

计算总计

然后我在主线程上有一个函数来计算walkDistance的总和。它将由 commitWrite 上的 Realm 通知触发。

- (void)calculateTotal
{
    assert([NSThread isMainThread]);
    NSNumber *total = [self.persons sumOfProperty:@"walkDistance"];
    double miles = 0;
    for (Person *person in self.persons) {
        miles += [person.walkDistance doubleValue];
    }
    NSString *title = [NSString stringWithFormat:@"%@ - %0.0f", total, miles];
    NSLog(@"%@", title);
}

问题

问题是当我用按钮触发clearDB 时,大多数时候我用sumOfProperty 方法得到的总距离为0。 for 循环添加始终有效。

从日志来看,似乎有两个通知被触发,calculateTotal 被调用了两次,一次在清除之后,一次在人口之后。但是sumOfProperty 似乎大部分时间都坚持第一个时间值,即 0。您可以看到日志的最后一行显示 0 - 6 而应该是 6 - 6

NSLog 输出

2015-12-10 21:25:38.686 dbrealmtest[18746:3258269] start 1
2015-12-10 21:25:38.686 dbrealmtest[18746:3258213] 1.358118751448067e-312 - 0
2015-12-10 21:25:38.692 dbrealmtest[18746:3258269] end 1
2015-12-10 21:25:38.693 dbrealmtest[18746:3258213] 0 - 6

这是一个已知问题吗?一个错误?还是我错过了什么?

谢谢

【问题讨论】:

  • 我建议,如果你不检查你根本没有通过的错误指针。这将导致 Realm 的初始化程序引发异常,这会在日志中为您提供比 assert(realm != nil) 更有用的错误消息。
  • Yo 写道“它们都使用 GCD 相同的队列。所以它们在同一个线程上并按顺序运行。”。这不是真的。 GCD 不保证主队列旁边的执行线程。
  • @marius 我不明白你的第一条评论。你能再解释一下吗?对于第二条评论,是的。你说的对。它们不是由同一个线程执行的,而是按顺序执行的。这就是为什么我在每个 dispatch_async 的开头添加一个语句来获取一个新的 Realm。但它应该不会导致我看到的问题,对吧?
  • @marius 创建领域中的断言始终通过。所以在每一个后台线程中,Realm都创建成功了。
  • 你是对的。关于 GCD 的事实并没有导致问题,你在这里看到。我只是指出这一点以供进一步参考,以便您和其他人不要基于错误的假设。 :)

标签: ios objective-c multithreading realm


【解决方案1】:

记录更新:在further investigation 之后发现这是一个错误,自 0.97.1 版以来已修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多