移动端 realm数据库使用及解耦,跨线程安全使用 OC realm

本文探讨了在高并发IM应用中,如何通过解耦Realm以避免线程同步问题。作者介绍了使用IMSessionDaoScheme类来隔离数据模型,确保跨线程安全,并分享了如何在项目中安全地进行查询、更新和数据隔离的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在搞IM,因为消息量多,实时读写及并发相当的多,原项目封装使用了FMDB,但这个东西对比于并发多线程读写实在不敢恭维,动不动出现锁导致卡顿,体验极期扯蛋。虽然实现队列读写,但是还是管不住这东西的缺陷。。于是乎寻找替换方案。

首先考虑了WCDB,即微信团队发布的开源数据库,但是使用起来相当的别扭,所有属性字段得一个一个的去使用他的宏去声明,工作太繁锁,相信软件及开源的初衷一定是减少开发者的代码耦合及胶水坨坨。

再次考虑都查了Realm这个开源库,库本身为500多M,使用后各种崩溃,100%都是跨线程使用,虽然这个东西,官方说明是线程并发安全的,经过测试也确实是安全的,但是当你使用不当,则全面崩溃异常。原因就是我们的原则数据处理在子线程,刷新UI在主线程。我们在子线程配合加载器(类似于toast)加载数据 ,在主线程使用刷新页面,这个时候,这个东东就不安全了,各种内部线程检查崩溃,对于已有的项目,去适配他的理念及其思想,明显是不明智的,你也不知道哪里要改,哪里要去检查,这样完完全全不是开发的思维,只会白白浪费时间与精力。

        故而在寻思realm的安全使用方案,不得不进行解耦,剥离他的内部线程管理方案。即我只用你保存、读取数据 ,页面中的数据model完全是独立于Realm管理的,这个使用方案必定会影响realm的使用性能,但是为了快速在项目中集成使用,不得不这么做。

        先来看看这个东西怎么使用:

        Realm官网介绍了很多,奈何时间有限,无法去通读,只能从网上查询总结一二,Realm最吸引人的优点就三点:

  1. 跨平台:现在很多应用都是要兼顾iOS和Android两个平台同时开发。如果两个平台都能使用相同的数据库,那就不用考虑内部数据的架构不同,使用Realm提供的API,可以使数据持久化层在两个平台上无差异化的转换。

  2. 简单易用:Core Data 和 SQLite 冗余、繁杂的知识和代码足以吓退绝大多数刚入门的开发者,而换用 Realm,则可以极大地减少学习成本,立即学会本地化存储的方法。毫不吹嘘的说,把官方最新文档完整看一遍,就完全可以上手开发了。

  3. 可视化:Realm 还提供了一个轻量级的数据库查看工具,在Mac Appstore 可以下载“Realm Browser”这个工具,开发者可以查看数据库当中的内容,执行简单的插入和删除数据的操作。毕竟,很多时候,开发者使用数据库的理由是因为要提供一些所谓的“知识库”。


“Realm Browser”这个工具调试起Realm数据库实在太好用了,强烈推荐。

如果使用模拟器进行调试,可以通过


[RLMRealmConfiguration defaultConfiguration].fileURL

打印出Realm 数据库地址,然后在Finder中⌘⇧G跳转到对应路径下,用Realm Browser打开对应的.realm文件就可以看到数据啦.

如果是使用真机调试的话“Xcode->Window->Devices(⌘⇧2)”,然后找到对应的设备与项目,点击Download Container,导出xcappdata文件后,显示包内容,进到AppData->Documents,使用Realm Browser打开.realm文件即可.

安全使用,这里我就直接贴这个兄台的分享经验内容:

Realm数据库 从入门到“放弃” - 简书

大家去看集成使用即可。本文的重点是在解耦,即在我们项目中安全的多线程中使用realm的读写。

贴上以下代码:IMSessionDaoScheme.h文件内容

//
//  IMSessionDaoScheme.h
//  IMCode
//
//  Created by carbonzhao on 2022/6/10.
//
//

#if __has_include(<Realm/Realm.h>)
#import <Realm/Realm.h>

@interface RLMStringModel : RLMObject
@property (copy,nonatomic) NSString *strValue;
@end

RLM_ARRAY_TYPE(RLMStringModel)


/**根据REALM原则 ,数据查询在什么线程则在什么线程使用,跨线程使用查询出来的RLMObject及其他对象,均会崩溃。IMSessionDaoScheme实现解耦,所有查询出来的RLMObject进行二次对象替换,保证数据为非REALM托管的对象。*/
@interface IMSessionDaoScheme : RLMObject

//RLMObject实现已经阉割了OC的RUNTIME方法,无法通过class_copyPropertyList来获取其属性及值
+ (NSArray <NSString *>*)allKeys;
- (NSMutableDictionary *)keysValues;
//增、改
- (void)save2Dao;
+ (void)save2Dao:(NSArray <IMSessionDaoScheme *>*)resArr;

//修改某个属性值
- (void)updateOncePropertyValue:(void (^)(id thisModel))ablock;

//删
- (void)deleteFromDao;
+ (void)deleteFromDao:(NSArray <IMSessionDaoScheme *>*)resArr;
+ (void)deleteAll;

+ (NSMutableArray <IMSessionDaoScheme *>*)queryAll;
+ (NSMutableArray <IMSessionDaoScheme *>*)queryFromDaoWithStatement:(NSDictionary *)stej;
+ (NSMutableArray <IMSessionDaoScheme *>*)queryFromDaoWithWhere:(NSString *)sttext;
/**查 ifAnd=yes,sql statement will be liked key=1 AND key1=2,other else key=1 OR key1=2....,
 sortedKey can be key desc,key1 asc,use ',' seperator the statement
 */
+ (NSMutableArray <IMSessionDaoScheme *>*)queryFromDaoWithStatement:(NSDictionary *)stej ifAnd:(BOOL)ifAnd sortedKey:(NSString *)sortedKey;
@end

// This protocol enables typed collections. i.e.:
// RLMArray<IMSessionDaoScheme *><IMSessionDaoScheme>
RLM_ARRAY_TYPE(IMSessionDaoScheme)

#endif

IMSessionDaoScheme.m文件内容

//
//  IMSessionDaoScheme.m
//  IMCode
//
//  Created by carbonzhao on 2022/6/10.
//
//

#import "IMSessionDaoScheme.h"
#import "JsonKit.h"
#import "NSExtentionSloter.h"
#import "IMDataConfigTools.h"

#if __has_include(<Realm/Realm.h>)

@implementation RLMStringModel

@end

@interface IMSessionDaoScheme ()
@property (nonatomic,strong) NSString *usersTable;

@property BOOL spcyInMainThread;
@end

@implementation IMSessionDaoScheme
#pragma mark - daoLayer
+ (NSArray *)ignoredProperties
{
    return @[@"spcyInMainThread"];
}


+ (NSArray *)allKeys
{
    Class csName = [self class];
    IMSessionDaoScheme *aj = [[csName a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhaocarbon

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值