【问题标题】:Realm Migration and Optional Properties领域迁移和可选属性
【发布时间】:2015-11-07 17:10:33
【问题描述】:

我最近将我的 Realm 库从 0.92(我认为)升级到了 0.96.2,但在对“可选”属性的新支持方面遇到了一些问题。我还需要第一次进行迁移,这也使事情变得复杂。

新方案需要向其中一种数据类型添加单个字段,因此我编写了一个迁移代码,在现有对象上建立了这个新属性:

RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 1;
config.migrationBlock = ^(RLMMigration* migration, uint64_t oldSchemaVersion)
{
    [migration enumerateObjects:Foo.className
                          block:^(RLMObject* oldObject, RLMObject* newObject) {
                              if (oldSchemaVersion < 1)
                              {
                                newObject[@"user"] = @"";
                              }
                          }];
};
[RLMRealmConfiguration setDefaultConfiguration:config];

但是,一旦代码尝试打开领域,我就会收到一条关于可选属性类型的错误消息:

'Migration is required for object type 'Person' due to the following errors:
- Property 'name' has been made optional.
- Property ‘company’ has been made optional.
- Property 'title' has been made optional.
- Property 'phone' has been made optional.
- Property 'email' has been made optional.
- Property 'homeAddress' has been made optional.'

问题 #1 - 由于模型从“必需”属性变为“可选”,因此可以保证现有对象已经存在值;所以我很难理解为什么需要迁移

问题 #2 - 我仍然喜欢 迁移对象,如果字符串为空,则将属性置空,因此我编写了迁移代码:

RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 1;
config.migrationBlock = ^(RLMMigration* migration, uint64_t oldSchemaVersion)
{
    NSLog(@"RUNNING REALM MIGRATION");

    // ...basic migration of adding a new property (above)

    [migration enumerateObjects:Person.className
                          block:^(RLMObject* oldObject, RLMObject* newObject) {
                              if (oldSchemaVersion < 1)
                              {
                                  if ([oldObject[@"name"] length] == 0)
                                      newObject[@"name"] = nil;
                                  else
                                      newObject[@"name"] = oldObject[@"name"];

                                  // … repeat for other properties
                }
                          }];
};
[RLMRealmConfiguration setDefaultConfiguration:config];

但是,迁移似乎没有运行; if (oldSchemaVersion &lt; 1) 块内的断点永远不会被命中,"RUNNING REALM MIGRATION" 消息永远不会打印。

外部块——设置RLMRealmConfiguration——被击中application:didFinishLaunchingWithOptions:

【问题讨论】:

    标签: objective-c realm


    【解决方案1】:

    问题 #1 默认情况下,所有属性在 0.96 之前的 Realm 版本中都被指定为“必需”。在 0.96 中,它们默认标记为“可选”。因此,由于新的基础文件格式发生了变化以适应这一点(相对不平凡的变化),因此需要进行迁移以将这些以前需要的属性转换为可选属性。

    如果您想根据需要保留这些属性,可以通过覆盖[RLMObject requiredProperties] 方法来定义它。

    问题 2 嗯...查看示例代码,建议您将枚举语句封装在if (oldSchemaVersion &lt; 1) 条件块内,而不是相反。这可能会导致事情发生混乱。您是否尝试过交换它?

    如果有帮助,请告诉我! :)

    【讨论】:

    • 谢谢,我没有注意到我翻转了枚举和条件块。但是我仍然遇到同样的问题:config.migrationBlock 似乎根本没有被执行。
    • 需要迁移才能将这些以前需要的属性转换为可选属性。 - 这该怎么做? -- 我试过了,只需要迁移,即使它是空的。
    【解决方案2】:

    问题似乎是我正在使用我的迁移信息设置默认的RLMRealmConfiguration,但[RLMRealm realmWithPath:] 忽略了默认配置。

    您可以复制默认配置(包括您的migrationBlockschemaVersion),而不是使用realmWithPath:,设置path 属性,并将其传递给[RLMRealm realmWithConfiguration:error:]

    RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
    config.path = file;
    
    NSError* error = nil;                    
    RLMRealm* realm = [RLMRealm realmWithConfiguration:config
                                                 error:&error];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-04
      相关资源
      最近更新 更多