移动端iOS系统数据库之Realm(四)解锁高级姿势
本文讲解一些realm非常有用功能,用处理及时消息例子来说明。例如及时通讯,直播观众席等等。
need-to-insert-img
xiaoxi.gif
67AB6A2B-3795-421B-8F88-6B00621AA477.png
一、目的
创建一张消息表来存储消息内容,设计字段为:
RLMMessage{mid:消息id 主键不能为空createdDate:消息创建时间不能为空mid:不能为空body:消息内容 不能为空read:消息是否已读 默认为未读}
代码
#import#import"RLMObject.h"@interfaceRLMMessage:RLMObject/*消息id 主键不能为空*/@propertyNSString*mid;/*消息创建时间 不能为空*/@propertyNSString*createdDate;/*消息内容 不能为空*/@propertyNSString*body;/*消息是否已读 默认为未读*/@propertyNSNumber<RLMBool>*read;/*属于我们自己操作用的属性,不需要存数据库*/@propertyBOOL selected;@endRLM_ARRAY_TYPE(RLMMessage)
实现
@implementationRLMMessage/*设置主键*/+(NSString*)primaryKey{return@"mid";}/*设置不能为空属性*/+(NSArray<NSString*>*)requiredProperties{return@[@"body",@"createdDate"];}/*设置为默认值*/+(nullable NSDictionary*)defaultPropertyValues{return@{@"read":@(NO)};}/*设置忽略属性,不存数据库*/+(NSArray<NSString*>*)ignoredProperties{return@[@"selected"];}@end
二、实现与传统数据库的功能
1、数据库主键
+ (NSString *)primaryKey{}
2、值不允许为null
+ (NSArray *)requiredProperties{}
3、建立索引
+ (NSArray *)indexedProperties{}
4、默认值
+ (NSDictionary *)defaultPropertyValues{}
、、、、
+数据库之外的功能
5、忽略某个模型属性不存数据库
+ (NSArray *)ignoredProperties{}
6、内存数据库
//配置内存数据库,应用杀死之后数据不会保存。 config.inMemoryIdentifier=@"memory";
、、、
+不能实现的功能
7、值自增,比如id自动+1
三、实用功能数据库监听
1、api
-(RLMNotificationToken *)addNotificationBlock:(RLMNotificationBlock)block __attribute__((warn_unused_result));
可以监听整个数据库的变化、也可以监听某张表的数据变化
本例用法,用来监听RLMMessage表的变化,有新消息来了之后刷新tableView
-(void)viewWillAppear:(BOOL)animated{[superviewWillAppear:animated];RPDataBase*db=[RPDataBase db];__weaktypeof(self)wself=self;_token=[[RLMMessage allObjectsInRealm:db]addNotificationBlock:^(RLMResults*_Nullable results,RLMCollectionChange*_Nullable change,NSError*_Nullable error){if(!change||error){return;}[wself.msgs addObject:[results lastObject]];NSIndexPath*inxp=[NSIndexPath indexPathForRow:wself.msgs.count-1inSection:0];[wself.tableView reloadData];}];}-(void)viewDidDisappear:(BOOL)animated{[superviewDidDisappear:animated];[_token stop];//移除_token=nil;}
模拟收到消息
/**模拟收到一条消息*/-(void)postMessage{NSDictionary*bodys=@{@(0):@"小明在不",@(1):@"小明今天天气不错呀",@(2):@"是的妮",@(3):@"出来逛街不",@(4):@"好呀好呀",@(5):@"逛完街吃饭去",@(6):@"ok"};intmid=CFAbsoluteTimeGetCurrent();NSDateFormatter*fmt=[[NSDateFormatter alloc]init];fmt.dateFormat=@"yyyy-MM-dd HH:mm:ss";//构建一条消息RLMMessage*msg=[[RLMMessage alloc]init];msg.mid=[NSString stringWithFormat:@"%d",mid];msg.createdDate=[fmt stringFromDate:[NSDate date]];msg.body=bodys[@(mid%6)];RPDataBase*db=[RPDataBase db];[db beginWriteTransaction];[db addObject:msg];[db commitWriteTransaction];[selfperformSelector:@selector(postMessage)withObject:nil afterDelay:1];}
监听一旦开启就会返回一个token,通过控制这个token才会使得监听停下,realm会单独开启一个线程来管理线程通知,另外也不是所有的数据库都可以用来监听,比如配置了只读数据库,源码在这里
-(RLMNotificationToken*)addNotificationBlock:(void(^)(RLMResults*,RLMCollectionChange*,NSError*))block{[_realm verifyNotificationsAreSupported];returnRLMAddNotificationBlock(self,_results,block,true);}-(void)verifyNotificationsAreSupported{[selfverifyThread];if(_realm->config().read_only()){@throwRLMException(@"Read-only Realms do not change and do not have change notifications");}if(!_realm->can_deliver_notifications()){@throwRLMException(@"Can only add notification blocks from within runloops.");}}
更多技能构建中。。。