【问题标题】:Realm.io: Sync or Async?Realm.io:同步还是异步?
【发布时间】:2016-02-26 02:49:54
【问题描述】:

我有一个函数sync,它会定期运行,以同步所有未同步的 Realm 模型(我在我的应用程序内部使用这个 sync 标志,只是为了检查我是否已经处理了模型)。

我使用 NSLock 作为保护,因为sync 可能会同时运行多次。

我遇到了一个问题,有时相同的模型会被多次处理。 我想知道我的代码中是否有任何问题,我该如何解决(我认为这可能是由于 realm.io 可能是异步的)。


@property (strong, nonatomic) NSLock *lock;

- (void)sync
{
    if (![self.lock tryLock]) return;

    RLMResults *models = [Model objectsWhere:@"sync = 0"];
    for (Model *model in models) {

        [realm beginWriteTransaction];
        model.sync = 1; // 1 step - Required to run the function.
        [realm commitWriteTransaction];

        [self myFunc]; // 2 step.

    [self.lock unlock];
}

- (void)myFunc
{
    NSLog(@"Updating view controller."):
}

【问题讨论】:

    标签: objective-c realm


    【解决方案1】:

    首先,如果您不需要将属性sync永久存储在您的数据库中,您也可以将其添加到您的ignoredProperties中,那么您根本不需要写事务。

    如果您有充分的理由将其存储在那里,您还可以使用写事务作为隐式锁定机制。

    我们建议使用 Realm 将写入事务分组到大批量而不是大量小事务。那是因为我们的MVCC 需要保留所有仍然被一个线程访问的版本,这个线程还没有更新。

    我提前解释了同步方法实际上做了更多的工作,而不是仅仅切换sync 标志并且myFunc 正在使用新数据更新视图控制器。如果sync 方法可以同时运行多次,则必须异步调用/从另一个线程运行,因为主队列不是并发的。而myFunc 必须在主线程上运行,因为您只能从那里更新您的 UI。这排除了它在这两种方法之间共享相同的 Realm 实例,因为访问器不是线程安全的。如果您在同步方法中的大批量写入事务中从另一个线程的 Realm 实例触发 UI 更新,则模型更新尚不可见。因此,您还需要批量更新 UI。

    - (void)sync {
        if (realm.inWriteTransaction) {
            return;
        }
        [realm beginWriteTransaction];
    
        RLMResults *models = [Model objectsWhere:@"sync = 0"];
        NSArray *modelIds = [models valueForKey:@"primaryKey"];
        for (Model *model in models) {
            model.sync = 1; // 1st step.
            // More expensive background work happens here?
        }
        [realm commitWriteTransaction];
    
        // Asynchronous batched 2nd step.
        dispatch_async(dispatch_get_main_queue(), ^{
            [self myFuncWithUpdatedModelIds:modelIds];
        });
    }
    

    【讨论】:

    • 小东西:[realm.inWriteTransaction] 应该是[realm inWriteTransaction]。
    猜你喜欢
    • 2017-06-22
    • 1970-01-01
    • 2019-01-17
    • 2020-05-15
    相关资源
    最近更新 更多