Thread safety issues with CoreData and SQLite multi-threaded access

Source: Internet
Author: User
Tags sqlite

Database read operations are typically accessed in multiple threads. When reading the data, we want to ensure that its current state can not be modified, that is, read the lock, otherwise there will be data error confusion.
There are two commonly used data persistence methods in iOS: CoreData and SQLite, both of which need to be thread-safe to explain thread-safe access to SQLite in Fmdb.

One: Fmdb thread safety: (take picture as an example)

1. There is no thread-safe way to perform:

123456789101112131415161718192021222324252627282930313233343536373839404142434445 //************** 数据库保存图片  ******************// FMDatabase *database = [FMDatabase databaseWithPath:[selfgetDatabasePath]]; //打开数据库 [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, using thread queue

12345678910111213141516171819202122232425262728293031323334353637383940414243 //************** 数据库线程安全 ***********//    FMDatabaseQueue *queue = [[FMDatabaseQueue alloc] initWithPath:[selfgetDatabasePath]];    [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];        }    }];

Analyze the implementation of Fmdb under thread safety:
When you create a database using Fmdbdatabasequeue, a thread queue is created with GCD:

12345 。。。 _queue = dispatch_queue_create([[NSStringstringWithFormat:@"fmdb.%@"self] UTF8String], NULL);        dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void*)selfNULL);        _openFlags = openFlags;。。。

The method is then called at read Time [queue inDatabase:^(FMDatabase *db) , and the current database is locked in the block

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

We can see that this is actually a lock-up of the entire database to ensure thread safety.

Second, CoreData thread safety

1. No thread-safe coredata data reads:

The creation of the Nsmanagedobjectcontext object:_managedObjectContext = [[NSManagedObjectContext alloc] init];

Insert Data operation: (Appdetailmodal as data model)

Context for the returned _managedobjectcontext

1 AppDetailModal *newapp = [NSEntityDescriptioninsertNewObjectForEntityForName:TableName inManagedObjectContext:context];

Other query, update, delete operations
Get entity

1 NSEntityDescription*entity = [NSEntityDescriptionentityForName:TableName inManagedObjectContext:context];

  

2. Thread-Safe CoreData operation:

Create a parallel Nsmanagedobjectcontext object first

1 NSManagedObjectContext* context=[[NSManagedObjectContextalloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

  

12345 然后在执行读取操作时使用一下两个方法:-(void)performBlock:(void (^)(void))block -(void)performBlockAndWait:(void(^)(void))block

  

12345 [context performBlock:^{        //要执行的读取操作 }];

Thread safety issues with CoreData and SQLite multi-threaded access

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.