将领域对象用作单一实例时出错.这是个好主意吗



我目前正在尝试在我的应用程序中使用 Realm,我想使用RLMObject的子类作为单例来存储应用程序状态。

我的第一个想法是,这是否是一个非常糟糕的主意。

我的AppState类有 2 个主要方法:

+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance = nil;
    RLMResults *result = [[self class] allObjects];
    if (result.count == 0) {
        dispatch_once(&once, ^{
            RLMRealm *realm = [RLMRealm defaultRealm];
            sharedInstance = [[self alloc] init];
            [realm beginWriteTransaction];
            [realm addObject:sharedInstance];
            [realm commitWriteTransaction];
        });
    }
    else {
        sharedInstance = [[[self class] allObjects] lastObject];
    }
    return sharedInstance;
}
- (void)update {
    RLMRealm *realm = self.realm;
    [realm beginWriteTransaction];
    [realm addOrUpdateObject:[[self class] sharedInstance]];
    [realm commitWriteTransaction];
}

我有用于存储有关应用程序状态的多个参数的属性。

在我的一个视图控制器中,我收到以下错误:

'尝试修改写入事务之外的对象 - 调用 首先在RLMRealm实例上开始写入事务。

发生错误的代码片段如下所示:

AppState *defaultState = [AppState sharedInstance];
defaultState.appStateX = newAppStateValue; // This is where the app crashes.
[defaultState update];

我在-(void)update方法中将self.realm更改为[RLMRealm defaultRealm]。没有骰子!

我觉得我对单例和/或RLMObject的理解存在根本性错误。任何帮助,不胜感激。


更新

根据坂本的回答,我修改了-(void)update方法,接受block作为参数。这种方法有很大的错误空间,但我可以继续并继续我当前的实现,而无需进行任何重大更改。

- (void)update:(void(^)(void))block {
    RLMRealm *realm = self.realm;
    [realm beginWriteTransaction];
    block();
    [realm commitWriteTransaction];
}

我更新块中的所有属性。

根据 Realm 文档 http://realm.io/docs/cocoa/0.89.1/

Realm 对象可以像常规对象一样独立实例化和使用。

将对象添加到 Realm 数据库后,您可以继续使用它,并且您对它所做的所有更改都将被保留(并且必须在写入事务中进行)。

[AppState sharedInstance]方法返回的对象已经添加到 Realm 中。因此,更改对象的属性需要如下写入事务。

AppState *defaultState = [AppState sharedInstance];
[defaultState.realm beginWriteTransaction];
defaultState.appStateX = newAppStateValue;
[defaultState.realm commitWriteTransaction];

最新更新