领域迁移和可选属性
Realm Migration and Optional Properties
我最近将我的 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];
但是,一旦代码尝试打开 Realm,我就会收到有关可选 属性 类型的错误消息:
'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 < 1)
块内的断点永远不会命中,并且 "RUNNING REALM MIGRATION"
消息永远不会打印。
外面的方块——设置RLMRealmConfiguration
——被打在里面application:didFinishLaunchingWithOptions:
问题 #1
默认情况下,所有属性在 0.96 之前的 Realm 版本中指定为 'required'。在 0.96 中,它们默认标记为 'optional'。因此,由于新的基础文件格式发生变化以适应这一点(相对重要的变化),需要进行迁移以将这些以前必需的属性转换为可选属性。
如果您希望根据需要保留这些属性,您可以通过重写 [RLMObject requiredProperties]
方法来定义它。
问题 2
嗯……看样例代码,建议把枚举语句封装在if (oldSchemaVersion < 1)
条件块里面,不要反过来。这可能会导致事情发生混乱。您是否尝试过交换它?
如果有帮助请告诉我! :)
问题似乎是我正在使用我的迁移信息设置默认 RLMRealmConfiguration
,但 [RLMRealm realmWithPath:]
忽略了默认配置。
而不是使用 realmWithPath:
,您可以复制默认配置(包括您的 migrationBlock
和 schemaVersion
),设置 path
属性,然后传递给 [RLMRealm realmWithConfiguration:error:]
RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
config.path = file;
NSError* error = nil;
RLMRealm* realm = [RLMRealm realmWithConfiguration:config
error:&error];
我最近将我的 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];
但是,一旦代码尝试打开 Realm,我就会收到有关可选 属性 类型的错误消息:
'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 < 1)
块内的断点永远不会命中,并且 "RUNNING REALM MIGRATION"
消息永远不会打印。
外面的方块——设置RLMRealmConfiguration
——被打在里面application:didFinishLaunchingWithOptions:
问题 #1 默认情况下,所有属性在 0.96 之前的 Realm 版本中指定为 'required'。在 0.96 中,它们默认标记为 'optional'。因此,由于新的基础文件格式发生变化以适应这一点(相对重要的变化),需要进行迁移以将这些以前必需的属性转换为可选属性。
如果您希望根据需要保留这些属性,您可以通过重写 [RLMObject requiredProperties]
方法来定义它。
问题 2
嗯……看样例代码,建议把枚举语句封装在if (oldSchemaVersion < 1)
条件块里面,不要反过来。这可能会导致事情发生混乱。您是否尝试过交换它?
如果有帮助请告诉我! :)
问题似乎是我正在使用我的迁移信息设置默认 RLMRealmConfiguration
,但 [RLMRealm realmWithPath:]
忽略了默认配置。
而不是使用 realmWithPath:
,您可以复制默认配置(包括您的 migrationBlock
和 schemaVersion
),设置 path
属性,然后传递给 [RLMRealm realmWithConfiguration:error:]
RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
config.path = file;
NSError* error = nil;
RLMRealm* realm = [RLMRealm realmWithConfiguration:config
error:&error];