2017数据库和缓存ios开发

Realm 数据库在iOS移动端的使用

2016-11-10  本文已影响2810人  小冰山口

昨天跟几个哥们儿吃饭, 大家聊到数据库, 也谈到了 FMDB 和 CoreData 的优缺点, 突然发现 CoreData 我只记得个大概了, 其实除了 FMDB 和 CoreData, 还有一种常用的数据库是 Realm数据库.

FMDB 操作的是 SQLite 数据库, CoreData 底层其实也是操作 SQLite 数据库, 只是 CoreData 不需要写 SQL 语句,而且 CoreData 是存储 OC 对象的.

Realm 也是存储对象的, 而且用法比较简单. 也不失为除 FMDB 和 CoreData 的另外一个选择, 遇到没听过这个的也可以装个 X

我们今天来用 Realm 数据库做一个简单的通讯录

静态库路径 添加库 安装插件

安装成功插件后, 我们 command + N 在新建文件的时候就可以找到这么个东东

Realm Model Object RLMObject 模型文件

这个模型文件的作用还是相当大的, 先按下不表

做通讯录当然离不开 tableView, 如果说 CoreData 是和 NSFetchedResultsController互相配合, 那么 Realm 就是用到了 RLMResults 这个关键类
tableView 的数据源就是这么个东东

ViewController.m

    // -------- 初始化数据源 --------
- (RLMResults<YFPerson *> *)resultsArray
{
    if (!_resultsArray) {
        
         /* 按照年龄来排序 */
        _resultsArray = [[YFPerson allObjects]sortedResultsUsingProperty:@"age" ascending:YES];
    }
    return _resultsArray;
}

初始化数据源数组的时候还可以设置按照什么排序, 在这里, 我就按照年龄来排序

还有一个关键类就是RLMNotificationToken,通知令牌就是当数据库里的元素一发生变化, 就调用 block 里的代码,也非常的方便好用
- (RLMNotificationToken *)notificationToken
{
    
    __weak typeof(self)weakSelf = self;
    if (!_notificationToken) {
        _notificationToken = [self.resultsArray addNotificationBlock:^(RLMResults<YFPerson *> * _Nullable results, RLMCollectionChange * _Nullable change, NSError * _Nullable error) {
            
            if (error) {
                NSLog(@"打开 realm 数据库失败,%@",error);
                return;
            }
            
             /* 如果数据库的变化为空, 则仅仅刷新 tableView */
            if (!change) {
                [weakSelf.tableView reloadData];
            }
            
             /* 如果变化不为空,则更新 tableView的数据源, 并刷新 tableView */
             /* tableView开始更新 */
            [weakSelf.tableView beginUpdates];
             /* tableView 删除数据 */
            [weakSelf.tableView deleteRowsAtIndexPaths:[change deletionsInSection:0] withRowAnimation:UITableViewRowAnimationTop];// 因为只有第0组,所以所有的更新都在第0组
            
             /* tableView 添加数据 */
            [weakSelf.tableView insertRowsAtIndexPaths:[change insertionsInSection:0] withRowAnimation:UITableViewRowAnimationTop];
             /* tableView 刷新数据 */
            [weakSelf.tableView reloadRowsAtIndexPaths:[change modificationsInSection:0] withRowAnimation:UITableViewRowAnimationTop];
             /* tableView 结束更新 */
            [weakSelf.tableView endUpdates];
        }];
    }
    
     /* 在这里打印一下沙盒的地址, 然后可以看到待会儿可以看到可视化的数据库 */
    NSLog(@"%@",NSHomeDirectory());
    
    return _notificationToken;
}

我们在 block 回调里面插入数据,删除数据,刷新 tableView, 做这样一些操作. 当数据库数据一发生变化, 就会做相应的操作, 并刷新 tableView

在上面这个方法, 打印下沙盒地址, 等下用的着
1.增加单个联系人

RLMRealm 这个单例对象就是创建实例对象并存储到 Realm 数据库中

- (void)addUniquePerson
{
     /* 这个类是专门开始创建数据库的 */
     /* 开始写入业务 */
    [[RLMRealm defaultRealm]beginWriteTransaction];
    
     /* 这个方法是创造一个Realm实例对象,并存储到 Realm 数据库中 */
    [YFPerson createInRealm:[RLMRealm defaultRealm] withValue:@[[self randomName],@([self randomAge])]];
    
     /* 提交写入业务 */
    [[RLMRealm defaultRealm]commitWriteTransaction];
}

很有必要说一下[YFPerson createInRealm:[RLMRealm defaultRealm] withValue:@[[self randomName],@([self randomAge])]];这个方法, 这个方法是基于 KVC 的, 我们在设置 value 的时候可以传入NSJSONSerialization解析出来的数组和字典, 当传入数组的时候, 所有属性都必须填写, 并且要按这个模型对象定义属性时的顺序,否则就会报错

2.批量增加联系人

由于是耗时操作, 我们必须开启子线程

 /* 添加多个数据 */
- (void)addManyPersons
{
     /* 添加多个数据是耗时操作, 我们重新开启一个线程来操作 */
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       
        for (NSUInteger i = 0; i < 5; i++) {
            
             /* 循环内部的逻辑就跟添加单个数据一样了 */
           
            [[RLMRealm defaultRealm]beginWriteTransaction];
            [YFPerson createInRealm:[RLMRealm defaultRealm] withValue:@[[self randomName],@([self randomAge])]];
            [[RLMRealm defaultRealm]commitWriteTransaction];
        }
    });
}
只要增加和批量增加的方法被触发, 就会立马刷新到 tableView 上,并且顺序是按照年龄的升序来排列的, 这是才初始化数据源数组的时候设置好的
    // -------- 侧滑打开的方法 --------
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
     /* 删除数据,其实方法和添加数据是差不多的 */
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [[RLMRealm defaultRealm]beginWriteTransaction];
        [[RLMRealm defaultRealm]deleteObject:self.resultsArray[indexPath.row]];
        [[RLMRealm defaultRealm]commitWriteTransaction];
    }
}

整个效果做出来其实是这样的


效果图
那我们要看数据库在什么位置怎么办呢?

本文源码链接地址
Realm 数据库也是很博大精深的,大家一起探讨,感谢支持!

上一篇下一篇

猜你喜欢

热点阅读