美文网首页
Realm实战--多线程踩坑(二)

Realm实战--多线程踩坑(二)

作者: EvanTong | 来源:发表于2017-07-20 19:16 被阅读0次

接Realm实战--多线程踩坑(一):

www.jianshu.com/p/f77b28d7b6c7

错误案例二:

创建一个单例 RealmManagerFail2,实现数据库相关操作:

1、创建数据库:

@property(nonatomic,strong) dispatch_queue_t realmQueue;

- (void)createDataBase {

_realmQueue=dispatch_queue_create("realmQueue",NULL);

dispatch_async(_realmQueue, ^{

NSLog(@"createDataBase------当前线程是%@", [NSThread currentThread]);

NSArray*docPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

NSString*path = [docPath objectAtIndex:0];

NSString*filePath = [path stringByAppendingPathComponent:@"test.realm"];

NSLog(@"realm22222 ====数据库目录======= %@", filePath);

RLMRealmConfiguration*config = [RLMRealmConfiguration defaultConfiguration];

config.fileURL= [NSURL URLWithString:filePath];

config.readOnly=NO;

config.schemaVersion=1.0;

[RLMRealmConfiguration setDefaultConfiguration:config];

});

}

2、添加对象

- (void)addPerson:(Person*)person {

dispatch_async(_realmQueue, ^{

NSLog(@"addPerson-----当前线程是%@", [NSThread currentThread]);

RLMRealm*realm = [RLMRealm realmWithConfiguration:[RLMRealmConfiguration defaultConfiguration] error:nil];

[realm transactionWithBlock:^{

[realm addOrUpdateObject:person];

}];

NSLog(@"Tony来了");

});

}

3、操作数据库,狗狗长大

- (void)dogsGrowUpForMaster:(Person*)person {

dispatch_async(_realmQueue, ^{

NSLog(@"dogsGrowUpForMaster-----当前线程是%@", [NSThread currentThread]);

RLMRealm*realm = [RLMRealm realmWithConfiguration:[RLMRealmConfiguration defaultConfiguration]error:nil];

for(inti =0; i < person.dogs.count; i++) {

Dog*dog = person.dogs[i];

dispatch_async(_realmQueue, ^{

NSLog(@"某一只小狗长大了--------当前线程是%@", [NSThread currentThread]);

[self doSomeThingsCompleteBlock:^{

[realm transactionWithBlock:^{

dog.age=3;

}];

}];

});

}

});

}

- (void)doSomeThingsCompleteBlock:(void(^)(void))complete {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

NSIntegerdelay =arc4random() %3;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay *NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

complete();

});

});

}

4、外部调用

- (void)testFunc2 {

[[RealmManagerFail2sharedInstance]createDataBase];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

[[RealmManagerFail2sharedInstance]addPerson:_person];

});

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

[[RealmManagerFail2sharedInstance]dogsGrowUpForMaster:_person];

});

}

5、运行,奔溃。打印结果如下:

createDataBase------当前线程是 <NSThread: 0x608000268b00> {number = 3, name = (null)}

addPerson-----当前线程是 <NSThread: 0x608000268b00> {number = 3, name = (null)}

dogsGrowUpForMaster-----当前线程是 <NSThread: 0x60800026f2c0> {number = 5, name = (null)}

*** Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread.'

6、解释说明

与单例一(见上一篇)类似,该单例也实现了以下方法:创建数据库、添加对象、操作数据库。

唯一不同的是,这个单例中为了将数据库相关的操作放在同一个线程中,使用的方法是定义了一个线程队列的成员变量。所有的数据库操作均放在该队列分配的子线程中,如下

dispatch_async(_realmQueue, ^{

xxxxx

});

然而事与愿违的是,addPerson、dogsGrowUp方法中,确实保证了在同一个子线程中,而在doSomeThingsCompleteBlock: 方法中,因为嵌套了一层dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{}),出现了不同的子线程。

从而可以得出的猜测是,该队列在同一个线程中,会随机分类一个子线程供执行代码。嵌套子线程后,分配的子线程也随之改变。因此通过同一个队列,来实现所有操作均放在同一个线程中的方法,是不对的。

待续...

相关文章

  • Realm实战--多线程踩坑(二)

    接Realm实战--多线程踩坑(一): www.jianshu.com/p/f77b28d7b6c7 错误案例二:...

  • Realm实战--多线程踩坑(一)

    前言 Realm:移动应用数据库。 本文主要想探讨的问题是Realm在多线程使用上的坑,而并不具体介绍Realm的...

  • Realm踩坑笔记

    [TOC] Realm,为移动设备而生!替代 SQLite 和 Core Data。为你省下数周的时间和数千行的代...

  • [翻译]Realm Advanced Guides - Thre

    Realm Advanced Guides - Threading Realm 高级教程 —— 多线程 原文地址:...

  • Realm数据库使用及踩坑(Android-Kotlin)

    前言 最近公司新开发了个项目,其中使用到了Realm数据库,在此对Realm数据库的使用及踩坑进行下总结。 Rea...

  • Android插件化热修复

    项目实战之插件化VirtualAPK 使用滴滴插件化方案 VirtualApk 源码解析VirtualAPK 踩坑...

  • Qt多线程编程爬坑笔记

    最近在工作中用到了Qt中的多线程,踩了不少坑,故作下笔记,警示后人 - -! Overview 使用多线程编程可以...

  • Taro 实战踩坑

    Taro 引用相对路径图片 直接将相对路径放在src属性中,不起作用,需要先import进来,最好把图片放到服务器...

  • AIDL踩坑实战

    AIDL理论 AIDL(Android 接口定义语言)可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相...

  • Swift: Realm自然排序的一种思路

    公司最近正在把iOS端的数据库从Core Data替换成Realm, 期间踩坑无数, 这里主要讲讲排序的问题.Re...

网友评论

      本文标题:Realm实战--多线程踩坑(二)

      本文链接:https://www.haomeiwen.com/subject/ysrjkxtx.html