[关闭]
@chinese-ppmt 2017-11-08T14:00:45.000000Z 字数 2986 阅读 1384

Realm源码注释 解读 <二>

Realm


2017-11-08 21:43:21 update

RLMResults

RLMLinkingObjects

RLMLinkingObjects是一个自动更新(auto-updating)的集合(链接到它父对象)对象.(由它的父类RLMResults可以更容易明白,源码如下:)

  1. @interface RLMLinkingObjects<RLMObjectType: RLMObject *> : RLMResults
  2. @end

+ (NSDictionary *)linkingObjectsProperties;

源码如下:

  1. //注意返回值字典的key和value值类型
  2. + (NSDictionary<NSString *, RLMPropertyDescriptor *> *)linkingObjectsProperties;

重写该方法来提供某个属性(Dog中的owners)链接到的父类模型(Person)的关系信息(必须用RLMPropertyDescriptor来描述,aPerson有dogs,aDog有主人owners)。

示例

有两个人aPersonbPerson,两条狗aDogbDogaDog属于aPersonbPerson公有;bDog只属于bPerson

需求:现在要把aPersonbPerson存储到本地 (关系图如下:)。
Person and Dog.png

直接上代码,方便拷入自己的demo中验证,所以注释都写在了代码中
  1. #import "AppDelegate.h"
  2. #import <Realm/Realm.h>
  3. @interface Dog : RLMObject
  4. @property NSString *name;
  5. @property NSInteger age;
  6. @property (readonly) RLMLinkingObjects *owners;
  7. @end
  8. RLM_ARRAY_TYPE(Dog)
  9. @interface Person : RLMObject
  10. @property NSString *name;
  11. @property RLMArray<Dog> *dogs;
  12. @property NSNumber<RLMInt> *age;
  13. @end
  14. @implementation Dog
  15. + (NSDictionary *)linkingObjectsProperties
  16. {
  17. return @{ @"owners": [RLMPropertyDescriptor descriptorWithClass:Person.class propertyName:@"dogs"] };
  18. }
  19. @end
  20. @implementation Person
  21. @end
  1. @implementation AppDelegate
  2. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  3. {
  4. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  5. self.window.rootViewController = [[UIViewController alloc] init];
  6. [self.window makeKeyAndVisible];
  7. NSURL *url = [RLMRealmConfiguration defaultConfiguration].fileURL;
  8. //根据URL移除本地已经存储的realm数据库
  9. [[NSFileManager defaultManager] removeItemAtURL:url error:nil];
  10. //创建一个aDog
  11. Dog *aDog = [[Dog alloc]init];
  12. aDog.name = @"aDogName";
  13. aDog.age = 5;
  14. //创建一个bDog
  15. Dog *bDog = [[Dog alloc]init];
  16. bDog.name = @"bDogName";
  17. bDog.age = 6;
  18. //新建一个aPerson
  19. Person *aPerson = [[Person alloc]init];
  20. aPerson.name = @"aPersonName";
  21. [aPerson.dogs addObject:aDog];
  22. //新建一个bPerson
  23. Person *bPerson = [[Person alloc]init];
  24. bPerson.name = @"bPersonName";
  25. [bPerson.dogs addObjects:@[aDog,bDog]];
  26. //创建一个defaultRealm数据库
  27. RLMRealm *realm = [RLMRealm defaultRealm];
  28. //realm数据库的读写都是在事务里完成
  29. [realm transactionWithBlock:^{
  30. //存入方式一:aPerson会在存储的时候根据KVC赋值给新建的一个Person模型,并将新建的存入realm.(person指针变了)
  31. [Person createInDefaultRealmWithValue:aPerson];
  32. [Person createInDefaultRealmWithValue:bPerson];
  33. //存入方式二:不用新建(person指针不变)
  34. [realm addObject:aPerson];
  35. [realm addObject:bPerson];
  36. }];
  37. //从defaultRealm读取所有的Dog模型(realm保存的是Person模型,但是能读出所有的Dog模型,good,决定入坑)
  38. RLMResults *allDogs = [Dog allObjects];
  39. for (Dog *dog in allDogs) {
  40. NSArray *ownerNames = [dog.owners valueForKeyPath:@"name"];
  41. NSLog(@"%@ has %lu owners (%@)", dog.name, (unsigned long)ownerNames.count, ownerNames);
  42. }
  43. return YES;
  44. }
  45. @end
运行结果及分析如下:

2中方式存储person.png

详细分析请看下面:

  1. 方式一3个打印log:

    createInDefaultRealmWithValue 详细说明

    第1个 log出自

    1. //aPerson中加入aDog,[aPerson.dogs addObject:aDog];
    2. [Person createInDefaultRealmWithValue:aPerson];

    第2、3个 log出自

    1. //bPerson中依次加入aDog、bDog,[bPerson.dogs addObjects:@[aDog,bDog]];
    2. [Person createInDefaultRealmWithValue:bPerson];
  2. 方式二2个打印log:

    addObject 详细说明

    第1个 log出自

    1. //全部([aPerson.dogs addObject:aDog];)
    2. [realm addObject:aPerson];
    3. //以及aDog部分([bPerson.dogs addObjects:@[aDog,bDog]];去掉bDog)
    4. [realm addObject:bPerson];

    第2个 log出自

    1. //上面后一部分去掉aDog那部分
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注