Realm -- oc版实践(下)

前言

如果您对Realm 基础还没有很了解的话,请阅读Realm -- oc版使用(上)
上篇中,我们已经讲了Realm 的数据模型,增删改查基础操作。
接下来,我们就来说说项目实践中“踩坑”。

数据模型必须继承RLMObject

与数据库操作相关的model当然要继承RLMObject,不过,我们可以新建model,专门用来接收服务端数据,利用MJExtension等方法,model转化成RLMmodel后进行存储,model的继承就与RLMObject没有关系了,虽然model可以继承任意类型,但是如果有多个RLMmodel存在,就要实现多个model,文件增加,维护起来不方便。(有利有弊)

下图是上述思想的扩展,所有的数据库基础操作都在BaseDBModel中完成。

image.png
Realm不支持集合类型
  • 集合类型:NSArray,NSMutableArray,NSDictionary,NSMutableDictionary,NSSet,NSMutableSet等。
    比如,服务端返回数据中存在字典,可以把字典中key提出来,新建一个RLMObject�模型,与之前的模型创建关系,或者只能把字典转换成NSString或者NSData类型进行存储。
Realm的加密方案

在创建 Realm 数据库时采用64位的密钥对数据库文件进行 AES-256+SHA2 加密,通过设置encryptionKey 进行加密。

RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
NSString *path = [self db_currentRealmPath];
if (path) {
            configuration.fileURL = [NSURL fileURLWithPath:path];
}
#ifdef DEBUG
configuration.encryptionKey = nil;
#else
configuration.encryptionKey = [self db_getKey];
#endif
NSError *e = nil;
realm = [RLMRealm realmWithConfiguration:configuration error:&e];

以下是Realm的UI更新通知,项目中还未使用

Realm 通知

Realm 的写操作事务被提交之后,无论这个事务发生在何种线程或者何种进程之中,这个通知处理闭包都将会被触发:

// 获取 Realm 通知
token = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) { 
  [myViewController updateUI];
}];// 随后
[token stop];

集合通知
包括:已插入对象已删除对象,或者已修改对象的索引,这三种操作的通知。
集合通知是异步触发的,首先它会在初始结果出现的时候触发,随后当某个写入事务改变了集合中的所有或者某个对象的时候,通知都会再次触发。

 // 观察 RLMResults 通知
  __weak typeof(self) weakSelf = self;
  self.notificationToken = [[Person objectsWhere:@"age > 5"] addNotificationBlock:^(RLMResults<Person *> *results, RLMCollectionChange *changes, NSError *error) {
    if (error) {
      NSLog(@"Failed to open Realm on background worker: %@", error);
      return;
    }

    UITableView *tableView = weakSelf.tableView;
    // 对于变化信息来说,检索的初次运行将会传递 nil
    if (!changes) {
      [tableView reloadData];
      return;
    }

    // 检索结果被改变,因此将它们应用到 UITableView 当中
    [tableView beginUpdates];
    [tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
  }];
  }

对象通知
Realm 支持对象级别的通知。
在此对象被删除时、被修改时获取相应的通知。

RLMStepCounter *counter = [[RLMStepCounter alloc] init];
counter.steps = 0;
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm addObject:counter];
[realm commitWriteTransaction];
    __block RLMNotificationToken *token = [counter addNotificationBlock:^(BOOL deleted,
                                                                          NSArray<RLMPropertyChange *> *changes,
                                                                          NSError *error) {
        if (deleted) {
            NSLog(@"The object was deleted.");
        } else if (error) {
            NSLog(@"An error occurred: %@", error);
        } else {
            
            [token stop];
            token = nil;
        }
        
    }];

UI更新通知

  • [RLMCollection addNotificationBlock:]
// Observe RLMResults Notifications
__weak typeof(self) weakSelf = self;
//self.notificationToken -- >RLMNotificationToken 
//self.collection -->id<RLMCollection> collection 对应返回的RLMResults
self.notificationToken = [self.collection addNotificationBlock:^(RLMResults<Item *> *results, RLMCollectionChange *changes, NSError *error) {
  if (error) {
    NSLog(@"Failed to open Realm on background worker: %@", error);
    return;
  }

  UITableView *tableView = weakSelf.tableView;
  // Initial run of the query will pass nil for the change information
  if (!changes) {
    [tableView reloadData];
    return;
  }

  // Query results have changed, so apply them to the UITableView
  [tableView beginUpdates];
  [tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
                   withRowAnimation:UITableViewRowAnimationAutomatic];
  [tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
                   withRowAnimation:UITableViewRowAnimationAutomatic];
  [tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
                   withRowAnimation:UITableViewRowAnimationAutomatic];
  [tableView endUpdates];
}];

- (void)insertItem {
  // Perform an interface-driven write on the main thread:
  [self.collection.realm beginWriteTransaction];
  [self.collection insertObject:[Item new] atIndex:0];
  // And mirror it instantly in the UI
  [tableView insertRowsAtIndexPaths:[NSIndexPath indexPathForRow:0 inSection:0]
                   withRowAnimation:UITableViewRowAnimationAutomatic];
  // Making sure the change notification doesn't apply the change a second time
  [self.collection.realm commitWriteTransactionWithoutNotifying:@[token]];
}

通过本次项目中使用realm开始学习,发现更多基础知识可以先从官方文档看起,然后循循渐进,通过阅读github相关资料的源码,更深入学习realm。

强烈推荐
Realm数据库 从入门到“放弃”
该文章还较详细的介绍了从其他数据库迁移到Realm中的问题,还有其他realm的优缺点,很赞。

有意见或建议请评论留言,新人写技术文章,谢谢大家指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容