关于CoreData和SQLite多线程访问时的线程安全问题

转载 2015年07月09日 11:46:31

关于CoreData和SQLite多线程访问时的线程安全问题

数据库读取操作一般都是多线程访问的。在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱。 
IOS中常用的两种数据持久化存储方式:CoreData和SQLite,两者都需要设置线程安全,在这里以FMDB来解释对SQLite的线程安全访问。

一:FMDB的线程安全:(以读取图片为例)

1.没有线程安全的执行方式:

//************** 数据库保存图片  ******************//

    FMDatabase *database = [FMDatabase databaseWithPath:[self getDatabasePath]];

    //打开数据库

    [database open];

    NSString *sql = @"create table if not exists Test (id integer primary key autoincrement,name text,image blob);";

    //创建表

    [database executeUpdate:sql];

    //把UIImage对象转化为NSData

    NSData *data = UIImagePNGRepresentation([UIImage imageNamed:@"user_browse"]);    

    //写入数据

    sql = @"insert into Test (name,image) values (?,?)";

    [database executeUpdate:sql,@"张三",data];

    //读取显示

    sql = @"select * from Test;";

    FMResultSet *resultSet = [database executeQuery:sql];

    while (resultSet.next)

    {

        //[resultSet dataForColumn:@"image"];

        NSData *imageData = [resultSet dataForColumnIndex:2];

        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];

        imageView.image = [UIImage imageWithData:imageData];

        [self.view addSubview:imageView];

    }
2,使用线程队列

//************** 数据库线程安全 ***********//
    FMDatabaseQueue *queue = [[FMDatabaseQueue alloc] initWithPath:[self getDatabasePath]];

    [queue inDatabase:^(FMDatabase *db) {

        //线程安全的

        __block NSString *sql = @"create table if not exists Test (id integer primary key autoincrement,name text,image blob);";

        //创建表

        [database executeUpdate:sql];

    }];

    //插入数据

    [queue inDatabase:^(FMDatabase *db) {

        //写入数据

        sql = @"insert into Test (name,image) values (?,?)";

        [database executeUpdate:sql,@"张三",data];

    }];

    //读取
    [queue inDatabase:^(FMDatabase *db) {
        //读取显示
        sql = @"select * from Test;";
        FMResultSet *resultSet = [database executeQuery:sql];
        while (resultSet.next)
        {
            //[resultSet dataForColumn:@"image"];

            NSData *imageData = [resultSet dataForColumnIndex:2];
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];

            imageView.image = [UIImage imageWithData:imageData];
            [self.view addSubview:imageView];
        }
    }];
分析一下线程安全下的FMDB的实现: 
在当使用FMDBDatabaseQueue创建数据库时,会使用GCD创建一个线程队列:

。。。
 _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
        dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL);
        _openFlags = openFlags;
。。。
然后在读取时调用[queue inDatabase:^(FMDatabase *db)方法,在block中会锁定当前数据库

dispatch_sync(_queue, ^() {
        FMDatabase *db = [self database];
        block(db);
    ……
}

1.没有线程安全的coredata数据读取:

NSManagedObjectContext对象的创建:_managedObjectContext = [[NSManagedObjectContext alloc] init];

插入数据操作:(AppDetailModal为数据模型)

context 为返回的 _managedObjectContext

AppDetailModal *newapp = [NSEntityDescription insertNewObjectForEntityForName:TableName inManagedObjectContext:context];
其他查询、更新、删除操作 
//获取Entity
    NSEntityDescription *entity = [NSEntityDescription entityForName:TableName inManagedObjectContext:context];

2.线程安全的coreData操作:

首先创建并行的NSManagedObjectContext对象

NSManagedObjectContext* context=[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 

然后在执行读取操作时使用一下两个方法:

  • -(void)performBlock:(void (^)(void))block

  • -(void)performBlockAndWait:(void (^)(void))block

[context performBlock:^{

        //要执行的读取操作

 }];


关于CoreData和SQLite多线程访问时的线程安全问题

关于CoreData和SQLite多线程访问时的线程安全问题数据库读取操作一般都是多线程访问的。在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱。 IOS中...
  • hanangellove
  • hanangellove
  • 2015年04月09日 22:24
  • 5054

iOS Coredata安全之多线程

今天去一家公司面试,被问到coredata是怎么处理
  • xiaowenwen1010
  • xiaowenwen1010
  • 2014年09月25日 00:25
  • 1702

iOS CoreData详解(五)多线程

原创blog,转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK详解专栏,这里有很多基础的文章 http://blog.csdn.net/column/d...
  • Hello_Hwc
  • Hello_Hwc
  • 2015年06月01日 09:09
  • 4056

关于Android SQLite3多线程并发问题,学习笔记。

最近有看到过Sqlite3的相关文章,在这做一下学习笔记,
  • RockCode_li
  • RockCode_li
  • 2014年09月03日 10:54
  • 6126

iOS 持久化存储之CoreData VS 直接SQlite

原创Blog,转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK详解专栏 http://blog.csdn.net/column/details/huan...
  • Hello_Hwc
  • Hello_Hwc
  • 2015年07月12日 11:03
  • 6982

ios数据库sqlite-第三方框架FMDB,关于线程安全的事务处理

ios数据库sqlite-第三方框架FMDB,关于线程安全的事务处理 第一种情况 线程安全,解决同时取钱透支问题(上面解决) 第二种情况 转账:钱划出去了,进账:钱划进来,转出去了,但因为网络断网或者...
  • zx6268476
  • zx6268476
  • 2015年05月19日 10:42
  • 1716

sqlite与coreData的简单比较

前些时日,面试一家公司,对方的面试考官问我对于这两个区别有什么看法。以前项目里边只顾着写,没想太多,简单的答复 coreData提供ORM(Object Relationships Mapping)解...
  • zhang7761
  • zhang7761
  • 2015年03月27日 11:33
  • 1148

多线程_线程安全问题的产生原因分析

package cn.itcast_09; /* * 如何解决线程安全问题呢? * * 要想解决问题,就要知道哪些原因会导致出问题:(而且这些原因也是以后我们判断一个程序是否有线程安全问题的...
  • L1585931143
  • L1585931143
  • 2017年03月12日 20:06
  • 619

CoreData 多线程处理大量数据同步时的操作

CoreData是CoCoa中处理数据绑定数据的关键特性,提供完整的对象持久化存储方案。如果你使用sqlite3厌倦了敲打sql语句,CoreData正解决了你这烦恼。sqlite3是CoreData...
  • leikezhu1981
  • leikezhu1981
  • 2015年06月01日 02:28
  • 4256

coredata与sqlite之间的区别和联系

iOS 转载 sqlite数据库操作的基本流程是, 创建数据库, 再通过定义一些字段来定义表格结构, 可以利用sql语句向表格中插入记录, 删除记录, 修改记录, 表格之间也可以建立联系。  ...
  • qq_19697705
  • qq_19697705
  • 2015年04月03日 10:04
  • 1650
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于CoreData和SQLite多线程访问时的线程安全问题
举报原因:
原因补充:

(最多只允许输入30个字)