剛開始學習使用Realm時,看到有的示例代碼使用createInDefaultRealmWithValue創(chuàng)建新的Realm對象开睡,有的使用[realm addObject:]創(chuàng)建新對象害驹,對兩者的區(qū)別并不十分清楚鞭呕。直到今天定位一個問題才發(fā)現(xiàn)區(qū)別大了。
Person *person = [[Person alloc] init];
person.personId = @"3456";
person.sex = @"man";
person.status = YES;
[realm transactionWithBlock:^{
// [realm addObject:person];
[Person createInDefaultRealmWithValue:person];
}];
Dog *dog1 = [Dog new];
dog1.num = 1;
dog1.name = @"aaa";
[realm transactionWithBlock:^{
[realm addObject:dog1];
[person.pets addObject:dog1];
}];
NSLog(@"pets count is %zd", person.pets.count);
[realm transactionWithBlock:^{
Person* personGet = [Person objectForPrimaryKey:@"3456"];
NSLog(@"delay pets count is %zd", personGet.pets.count);
}];
見上面的代碼宛官,打印日志結果為:
pets count is 1
delay pets count is 0
看上去[person.pets addObject:dog1]
這一句并沒有對RLMArray屬性數(shù)組寫入成功葫松,但也沒有報錯,為什么會有這樣的結果呢底洗?
可以看一下 Realm源碼注釋 解讀 <二> 這里面的一段代碼注釋:
[realm transactionWithBlock:^{
//存入方式一:aPerson會在存儲的時候根據(jù)KVC賦值給新建的一個Person模型腋么,并將新建的存入realm.(person指針變了)
[Person createInDefaultRealmWithValue:aPerson];
[Person createInDefaultRealmWithValue:bPerson];
//存入方式二:不用新建(person指針不變)
[realm addObject:aPerson];
[realm addObject:bPerson];
}];
重點在于這一句:存入方式一:aPerson會在存儲的時候根據(jù)KVC賦值給新建的一個Person模型,并將新建的存入realm.(person指針變了)
亥揖,這說明使用createInDefaultRealmWithValue進行存儲時并不 是直接保存value參數(shù)党晋,而是在內部新建一個Person模型,通過遍歷value參數(shù)的屬性列表對新的Person模型進行賦值的。也就是說使用這種方式時存儲在Realm模型的Person對象與參數(shù)Person對象不是同一個對象未玻,指針是不一樣的,盡管它們的屬性值相同胡控。
這里就要說到一個Realm的修改原則:通過transactionWithBlock對一個模型進行修改時扳剿,這個模型一定要是被Realm管理的模型。通過這個例子昼激,是不是對這句話的理解更透徹庇绽?
另一段示例代碼:
//獲取Realm對象
RLMRealm *realm = [RLMRealm defaultRealm];
Student *stu4 = [[Student alloc]initWithValue:@{@"num": @4, @"name":@"titan4"}];
//添加數(shù)據(jù)
[realm transactionWithBlock:^{
//添加模型
[realm addObject:stu4];
// 這個模型stu, 已經被realm 所管理, 而且, 已經和磁盤上的對象, 進行的地址映射
}];
// 這里修改的模型, 一定是被realm所管理的模型
[realm transactionWithBlock:^{
stu4.name = @"coder4";
}];
換一種方式來解釋第二段代碼,那就是橙困,[Person createInDefaultRealmWithValue:aPerson]
中的參數(shù)aPerson不是被realm管理的模型瞧掺,這個方法返回的Person對象才是;[realm addObject:aPerson]
中的參數(shù)aPerson是被realm管理的模型
搞清楚原理了凡傅,那么對第一段的問題代碼辟狈,有3種解決辦法:
- 在
Person *person
前面加上__block,[Person createInDefaultRealmWithValue:person];
改成person=[Person createInDefaultRealmWithValue:person];
- 在
[person.pets addObject:dog1]
的下一行加入[[RLMRealm defaultRealm] addOrUpdateObject:person]
- 把
[Person createInDefaultRealmWithValue:person]
替換成[realm addObject:person]
顯然使用[realm addObject:person]
是最方便最省事的方法夏跷,所以能使用就用[realm addObject:]
吧