我注意到在Realm中设置PK不是强制性的,只是可以省略。但在文件中声明:
自动为主键属性创建索引。
我想澄清一些问题:
1)如果我不自己分配PK,则默认值是由Realm定义的。它是哈希还是其他什么? (如果我没有设置PK并致电[MyRealmObject primaryKey]
,则会返回nil
)
2)如果默认情况下对此隐式PK进行索引?我应该担心它,因为如果它没有被索引,是否意味着它会影响这个实体的一般性能(例如,获取对象)?
3)每次为每个RLMObject
子类定义PK是一个好习惯,还是Realm不需要它,并且可以依赖它由Realm本身定义的内部实现?
答案 0 :(得分:16)
(免责声明:我为Realm工作。)
是的!在Realm中设置主键不是强制性的,也不是必需的,这就是为什么它完全取决于开发人员和应用程序的要求,以确定它们在实现中是否有必要。
回答你的问题:
1)没有默认值;您将自己的一个属性指定为主键。 primaryKey
默认返回nil,因为您需要自己覆盖它,以便向Realm指示您想要充当主键的属性。有些用户将整数设置为主键,但通常使用UUID字符串是最常见的。
2)没有隐含的主键。您必须使用[RLMObject primaryKey]
方法明确说明哪个属性是主键,然后它将被索引。 :)
3)在我自己的(业余时间)开发经验中,我通常发现使用主键可以更容易地识别和处理特定对象。例如,如果您要跨线程传递对象,则只需传递主键值并使用[RLMObject objectForPrimaryKey:]
来重新获取对象。显然这取决于您自己的实现要求。你可能不应该添加一个主键,除非你发现你确实需要一个主键。
例如,如果您想将UUID字符串设置为主键,那么您将添加到RLMObject子类中:
@interface MyObject : RLMObject
@property NSString *uuid;
@end
@implementation MyObject
+ (NSString *)primaryKey
{
return @"uuid";
}
+ (NSDictionary *)defaultPropertyValues
{
@{@"uuid": [[NSUUID UUID] UUIDString]};
}
@end
我希望有所帮助!
附录:为了详细说明下面的一些注释,主要密钥对于任何根据数据库中是否已存在具有相同密钥的对象而更改其功能的Realm API显然是必需的。例如,如果具有该主键的对象不存在,+[RLMObject createOrUpdateInRealm:]
将向数据库添加新的Realm对象,否则将仅更新现有对象。
因此,在主键是后续逻辑的关键组件的这些实例中,它们是必需的。但是,由于这些API是可以在Realm中添加/更新数据的不同方式的子集,因此如果您选择不使用它们,则仍然不需要使用主键。
答案 1 :(得分:2)
这匹马已经被打死了,但我无法提供帮助,但是如果在没有主键的情况下创建或更新了Realm对象,那么引用异常会引发异常。
+ (instancetype)createOrUpdateInRealm:(RLMRealm *)realm withValue:(id)value {
// verify primary key
RLMObjectSchema *schema = [self sharedSchema];
if (!schema.primaryKeyProperty) {
NSString *reason = [NSString stringWithFormat:@"'%@' does not have a primary key and can not be updated", schema.className];
@throw [NSException exceptionWithName:@"RLMExecption" reason:reason userInfo:nil];
}
return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, true);
}