Menu
Woocommerce Menu

RealmSwift使用中相见的标题,关于eos岛屿的多少个预测

0 Comment


解决方法:
//解析使用 realm 不能有new alloc "copy", "mutableCopy" 等关键字前缀字段var newVehicleSuggestionPrice: String? = nilvar newVehicleNetPrice:String? = nil@objc dynamic var vehicleSuggestionPrice_realm: String? = nil@objc dynamic var vehicleNetPrice_realm: String? = nil//忽略realm数据库对应字段override static func ignoredProperties() -> [String] { return ["newVehicleSuggestionPrice","newVehicleNetPrice"] } //注意点:realmlist直接.append(objectsIn:)添加swift数组的时候,是可以添加到realmlist中的,原因realmlist数组能够识别swift数组类型,但是反之就不行 override func addRealmData() { self.vehicleSuggestionPrice_realm = self.newVehicleSuggestionPrice self.vehicleNetPrice_realm = self.newVehicleNetPrice }//注意点:swift数组直接.append(contentsOf:)添加realmlist的时候,是添加不到正常数组里的,原因正常的swift数组不识别realmlist类型,但是反之就可以 override func addOriginalData() { self.newVehicleSuggestionPrice = self.vehicleSuggestionPrice_realm self.newVehicleNetPrice = self.vehicleNetPrice_realm }
[root@localhost ~]# sudo -u ovirt jinfo 28823Attaching to process ID 28823, please wait...Debugger attached successfully.Server compiler detected.JVM version is 24.161-b00Java System Properties:jboss.modules.system.pkgs = org.jboss.bytemanlogging.configuration = file:///var/lib/ovirt-engine/jboss_runtime/config/ovirt-engine-logging.propertiesjava.vendor = Oracle Corporationjboss.qualified.host.name = localhost.localdomainsun.java.launcher = SUN_STANDARDsun.management.compiler = HotSpot 64-Bit Tiered Compilersjavax.xml.stream.XMLInputFactory = __redirected.__XMLInputFactorysun.nio.ch.bugLevel = os.name = Linux......

关于这点预测,估计很多玩家都不会同意,大陆才是母体,是月亮,小小海岛不过是卫星。说说自己的看法。

一.数据解析转换存储,反转换问题

由于项目中操作数据转换的地方多,需要Json转Model存入realm,获取realm数据Model转换成Json,但是realmSwift只支持把json转换成realm所需的存储Model,而不支持反转。而Android的realm却可以,这让我很苦恼,而我又不想手动一二个一个来转换,1是我们数据量太多,我觉得这种太耗费精力2是也觉得这样做有些low,于是乎遇到了瓶颈,逛各种技术论坛也没有找到解决方案。静下心来开始思考看HandyJson和realm的源码,最后发现原来realm的数据类型是它自己定义的数组类型,而不是继承iOSSwift的数据类型,这就造成HandyJson解析库识别不了这些数据类型,最后导致没办法数据相互转换。

图片 1realm数据类型

解决方案:1.建立数据Model的时候需要在BaseModel里添加两个方法函数解决list解析

import Foundationimport RealmSwiftimport Realmimport HandyJSONclass BaseRLMObject: Object, NSCopying { func copy(with zone: NSZone? = nil) -> Any { return type.init() } //这个父类添加的属性,子类解析不会赋值,因此在子类各自添加// @objc dynamic var primaryKey = UUID().uuidString// override static func primaryKey() -> String? {// return "primaryKey"// } //解析的Array数据添加到realm方法 例如:请求的Array数据需要添加到realm List数据库时调用 //注意点:realmlist直接.append(objectsIn:)添加swift数组的时候,是可以添加到realmlist中的,原因realmlist数组能够识别swift数组类型,但是反之就不行 func addRealmData(){ } //realm List数据传递给正常的Array方法 例如:realm List数据转换成model Array时调用 //注意点:swift数组直接.append(contentsOf:)添加realmlist的时候,是添加不到正常数组里的,原因正常的swift数组不识别realmlist类型,但是反之就可以 func addOriginalData(){ }}

2.子类需要继承父类,然后实现这两个方法,并且相同数组key属性都需要创建两个(一个是Json转换Realm数据需要,一个是Realm数据转换Json需要),每层都需要实现。3.需要在HandyJson的ignoredProperties中忽略正常的list数据,否则会在realm数据库的字段表中出现该字段。4.如果Bool型、Int型、Float型、Double型是需要非可空值的形式,则不需要特殊处理,但是如果这四种类型的数据是可空值形式,则需要特殊处理,转换成String类型。原因是Bool、Int、Float、Double的可空值形式是RealmOptional<类型>(),解析库识别不了realm自己定义的数据类型。具体代码:

import Foundationimport RealmSwiftimport Realmimport HandyJSONclass PhotoModel : BaseRLMObject, HandyJSON { @objc dynamic var primaryKey = UUID().uuidString override static func primaryKey() -> String? { return "primaryKey" }// let id = RealmOptional<Int>() @objc dynamic var id: String? = nil// let vehicleId = RealmOptional<Int>() @objc dynamic var type: String? = nil @objc dynamic var delFlag:Bool = false // 删除标记 let damageInfoList_realm: List<DamageInfoModel> = List<EQSDamageInfoModel>()//损伤点 var damageInfoList: [DamageInfoModel] = [] override static func ignoredProperties() -> [String] { return ["damageInfoList"] } override func addRealmData() { for item in self.damageInfoList { item.addRealmData() } if self.damageInfoList_realm.count > 0 && self.damageInfoList.count > 0 { self.damageInfoList_realm.removeAll() } self.damageInfoList_realm.append(objectsIn: self.damageInfoList) } override func addOriginalData() { if self.damageInfoList.count > 0 && self.damageInfoList_realm.count > 0{ self.damageInfoList.removeAll() } for item in self.damageInfoList_realm { item.addOriginalData() self.damageInfoList.append } }}

在使用的时候每次转换都需要调用add方法

//添加到realm数据库 if let object = JSONDeserializer<Model>.deserializeFrom(json: json) { object.addRealmData() SXRealm.addAsync } //realm数据库数据转换成Json let model = SXRealm.queryByPrimaryKey(DetailModel.self, primaryKey: detailModel.primaryKey) guard model == nil else { SXRealm.doWriteHandler { model.addOriginalData() } let json = mode.toJSON()! } 
[root@localhost ~]# sudo -u ovirt jinfo -flag HeapDumpOnOutOfMemoryError 28823-XX:+HeapDumpOnOutOfMemoryError[root@localhost ~]# sudo -u ovirt jinfo -flag -HeapDumpOnOutOfMemoryError 28823[root@localhost ~]# sudo -u ovirt jinfo -flag HeapDumpOnOutOfMemoryError 28823-XX:-HeapDumpOnOutOfMemoryError

在海岛开放前会有一段时间供玩家拍卖土地,neo海岛拍地十分火爆,“博弈”在拍地上体现的淋漓尽致,单价1neo的空地,最后涨到了5neo,更有石材木材钢材高新ro地,精彩刺激,拍卖土地都能当成一个游戏去玩。

二.primaryKey主键问题

经过测试逐渐定义不能在父类基础类定义,必须要在各个子类都要定义。Realm的机制可能是检测到这个字段有值就不会重新自动赋值,所以说不能偷懒在父类定义。

//这个父类添加的属性,子类解析不会赋值,因此在子类各自添加 @objc dynamic var primaryKey = UUID().uuidString override static func primaryKey() -> String? { return "primaryKey" }
  • 打印指定虚拟机运行参数的名称和值。

我想大家对赚钱效应这个词可能有误解。所谓赚钱效应,指的是在这个系统里有部分玩家可以实现高额回报,而不是人人都可以在这个系统里获得高额回报。

我们先来看下Realm不支持的地方及需要注意的地方:

1.不支持联合主键2.不支持自增长主键3.不能跨线程共享realm实例,不同线程中,都要创建独立的realm实例,只要配置(configuration)相同,它们操作的就是同一个实体数据库。4.存取只能以对象为单位,不能只查某个属性,使用sql时,可以单独查询某个独立属性,比如
select courseName from Courses where courseId = “001”,而在realm中 +
(RLMResults
*)objectsWhere类似这种返回的是RLMResults对象。查询相关函数,得到的都是对象的集合,相对不够灵活。5.被查询的RLMResults中的对象,任何的修改都会被直接同步到数据库中,所以对对象的修改都必须被包裹在beginWriteTransaction中,Swift要包裹在try!
Realm().write { }中,使用时要注意。例如:

let results = SXRealm.queryByAll(DetailModel.self) let item = results[0] try! Realm().write {//修改数据,必须在此操作中,否则会造成Crash。 item.uploadStatus = 2 item.uploadFailedDes = "上传失败!" } 

6.RLMResults与线程问题,在主线程查出来的数据,如果在其他线程被访问是不允许的,运行时会报错。例如:

//这种是错误的,只能访问同一线程的realm数据。 RLMResults *results = [Course objectsWhere:@"courseId = '001'"]; Course *getCourse = [results objectAtIndex:0]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"%@",results); NSLog(@"%@",getCourse.courseName); });

7.auto-updating机制,十分方便,并保证了数据的实时性,但是在个别情况下,也许这种机制并不需要,可能会导致一些意外,所以需要注意。

 RLMRealm *realm = [RLMRealm defaultRealm]; Course *course = [[Course alloc] init]; course.courseId = @"001"; course.courseName = @"语文"; [realm transactionWithBlock:^{ [realm addObject:course]; }]; Course *getCourse1 = [Course objectsWhere:@"courseId = '001'"].firstObject; NSLog(@"%@",getCourse1); [realm transactionWithBlock:^{ getCourse1.courseName = @"体育"; }]; NSLog(@"%@",course);

第一次查询后,result中有一条记录,后面即便没有执行重新查询,新加入的数据,自动就被同步到了result中。

 RLMRealm *realm = [RLMRealm defaultRealm]; Course *course = [[Course alloc] init]; course.courseId = @"001"; course.courseName = @"语文"; [realm beginWriteTransaction]; [Course createOrUpdateInDefaultRealmWithValue:course]; [realm commitWriteTransaction]; RLMResults *result = [Course allObjects]; NSLog(@"%@",result); Course *course2 = [[Course alloc] init]; course2.courseId = @"002"; course2.courseName = @"数学"; [realm beginWriteTransaction]; [Course createOrUpdateInDefaultRealmWithValue:course2]; [realm commitWriteTransaction]; NSLog(@"%@",result);

开始查询出课程id为001的课程模型getCourse1、getCourse2的课程名为语文,后面仅对getCourse2进行修改后,getCourse1的属性也被自动同步更新了。

 RLMRealm *realm = [RLMRealm defaultRealm]; Course *course = [[Course alloc] init]; course.courseId = @"001"; course.courseName = @"语文"; [realm beginWriteTransaction]; [Course createOrUpdateInDefaultRealmWithValue:course]; [realm commitWriteTransaction]; Course *getCourse1 = [Course objectsWhere:@"courseId = '001'"].firstObject; NSLog(@"%@",getCourse1); Course *getCourse2 = [Course objectsWhere:@"courseId = '001'"].firstObject; [realm beginWriteTransaction]; getCourse2.courseName = @"体育"; [realm commitWriteTransaction]; NSLog(@"%@",getCourse1);

.在别的线程中的修改,也会被同步过来

 Course *getCourse1 = [Course objectsWhere:@"courseId = '001'"].firstObject; NSLog(@"%@",getCourse1); dispatch_async(dispatch_get_global_queue, ^{ RLMRealm *realm = [RLMRealm defaultRealm]; Course *getCourse2 = [Course objectsWhere:@"courseId = '001'"].firstObject; [realm beginWriteTransaction]; getCourse2.courseName = @"体育"; [realm commitWriteTransaction]; NSLog(@"%@",getCourse2); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"%@",getCourse1); }); });

8.从realm数据库读取出的数据模型,setter/getter方法会失效,集成realmObject的实力类setter/getter方法会失效,当赋值的时候不会走set方法。到这里我们已经对Realm有了一定的了解,也熟悉了它的机制。

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。不用于商业目的,转载请注明出处。

在《对neoworld的一些看法》中就想着可能会有其他海岛,没想到这么快就又开了eos海岛,接下来其他海岛肯定也会逐步开放。

最近做个项目是需要大量的本地数据交互保存持久化操作,由于是新项目所以我们打算使用比较新颖的框架来进行开发,最后经过筛选使用了Realm来作为本地数据操作框架。name我们为什么选择realm呢?大部分的数据库框架还是使用2000年的SQLite,大部分的移动应用还是直接或间接的使用SQLite来作为本地数据库比如:FMDB、Couchbase
Lite,Core
Data,ORMLite,而Realm是专门为移动端设计的框架,最后我们经过比对选择了Realm。首先Realm
是一个跨平台的移动数据库引擎,其性能要优于 FMDB、Couchbase Lite,Core
Data,ORMLite – 移动端数据库性能比较, 我们可以在 Android 端
realm-javaKotlin也可以使用,iOS端:Realm-Cocoa,同时支持 OC 和
Swift两种语言开发。使用操作简单、性能优异、跨平台、开发效率得到了大大提高(省去了数据模型与表存储之间转化的很多工作)、配备可视化数据库查看工具。这些都满足了我们项目的需要。对于Realm的使用今天不在这里介绍,网上可以搜到很多具体的使用方法,也可以到官网文档上查看Api。我们主要剖析下在项目开发过程中遇到到问题、疑难杂症和解决的方案。

我十分同意海岛的发展会反哺于大陆,但是现在限于用户数量与规模,真的只能是想象。

五.realm数据对象不能带alloc、new、copy、mutableCopy之类的跟iOS语言相关的关键字、前缀字段,否则会造成Crash。那么我们只能够跟之前操作list的时候一样,同样的原理做桥接。

执行样例

因为eos的热度,所以eos海岛拍地肯定会比neo海岛更加刺激,更加激烈。neo海岛拍地时大家还都没经验,cbd区被一个老外初始50neo翻倍100neo承包,刚开始也是很多地都在初始价左右就被拍走,这种情况在eos海岛上应该不会再现了。

下面来说下在开发项目的时候具体碰到的问题:
  • 作用是实时地查看和调整虚拟机各项参数。
    • 使用 jps 命令的 -v
      参数可以查看虚拟机启动时显示指定的参数列表,但如果想知道未被显示指定的参数的系统默认值,除了查找资料以为,就只能使用
      jinfo 的 -flag 选项查询(JDK 1.6 及以上版本,可以使用 java
      -XX:+PrintFlagsFinal
      查看参数默认值) 。
    • 如果给定进程是在 64 位虚拟机上运行,那么需要指定参数
      -J-d64
  • 该工具仅限于报告其 具有访问权限 的虚拟机进程。

关于赚钱效应,jimi一针见血:

四.修改更新操作realm对象时,需要在写入操作中实现,并且只能有一层写入操作方法。
//在这如果做了doWrite操作,name在addOriginalData方法中就不能做都Write操作,否则Crash。SXRealm.doWriteHandler { model.addOriginalData() } static func doWriteHandler(_ clouse: @escaping  { // 这里用到了 Trailing 闭包 try! sharedInstance.write { clouse() } }
选项 说明
无选项 打印虚拟机运行参数和系统属性的名称、值对。
-flag <name> 打印指定虚拟机运行参数的名称和值。
-flag [+|-]name 启用或禁用指定的布尔参数标志。
-flag name=value 将指定的参数标志设置为指定值。
-flags 打印虚拟机运行参数标志对。
-sysprops 打印系统属性的名称、值对。
-h 打印帮助信息。
-help 打印帮助信息。

关于赚钱效应,我还想说两句,刚接触neoworld的时候,看到建筑90天之后拆除还会返95%成本这个设定非常不理解,而很多人还把这个设定当做拉玩家的一个理由,把前期收益搞这么高,就是在加速游戏生命周期,这不就是变形的寅吃卯粮,nash被疯狂砸盘,现在大陆发展缓慢我觉得跟这个有很大关系,虽然后来团队通过各种方式来调解限制,不过还是流失了很多用户,nash也被砸了很多。而在neo海岛中取消这种做法,外加其它的一些如jimi所称的“防撸设计”,让现在的整个游戏更为合理。

*以上就是RealmSwift的一些特性和我们项目中实践过程踩过的坑。如果之后使用过程中碰到问题,会持续更新。
[root@localhost ~]# java -XX:+PrintFlagsFinal|grep manageable intx CMSAbortablePrecleanWaitMillis = 100 {manageable} intx CMSWaitDuration = 2000 {manageable} bool HeapDumpAfterFullGC = false {manageable} bool HeapDumpBeforeFullGC = false {manageable} bool HeapDumpOnOutOfMemoryError = false {manageable} ccstr HeapDumpPath = {manageable} uintx MaxHeapFreeRatio = 100 {manageable} uintx MinHeapFreeRatio = 0 {manageable} bool PrintClassHistogram = false {manageable} bool PrintClassHistogramAfterFullGC = false {manageable} bool PrintClassHistogramBeforeFullGC = false {manageable} bool PrintConcurrentLocks = false {manageable} bool PrintGC = false {manageable} bool PrintGCDateStamps = false {manageable} bool PrintGCDetails = false {manageable} bool PrintGCTimeStamps = false {manageable}

之前写关于neoworld的有关文章时,觉得游戏的本质就是好玩,不好玩说什么都免谈,所以对neoworld评价比较低。最近看了火山哥的一些文章,比如《区块链游戏的本质是什么?》,对neoworld有了一些新的看法,neoworld中两大吸引我的地方,一是玩家博弈,二是赚钱效应,玩家博弈现在主要在大户层面体现,普通玩家比较难体验到,赚钱效应人人可参与,虽然伴随着熊市,以法币角度,大部分人都在亏钱。还是之前的观点:

标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图