领域sumOfProperty不提供最新更新

时间:2015-12-11 05:15:07

标签: ios objective-c multithreading 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中

在tableview中,我创建了RLMRealm self.databaseRLMResult 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:

我有一个函数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:

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

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

calculateTotal

然后我在主线程上有一个函数来计算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

这是一个已知问题吗?一个bug?或者我错过了什么?

由于

1 个答案:

答案 0 :(得分:0)

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