Thread safety for CoreData and SQLite multithreaded access

Source: Internet
Author: User
Tags sqlite

About thread safety issues with CoreData and SQLite multi-threaded access

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:

   Database save Picture ******************//fmdatabase *database = [Fmdatabase databasewithpath:[self getdatabase    Path]];    open databases [Database open];    NSString *sql = @ "CREATE table if not exists Test (ID integer primary key autoincrement,name text,image blob);";    CREATE TABLE [Database Executeupdate:sql];        Convert the UIImage object to NSData nsdata *data = uiimagepngrepresentation ([UIImage imagenamed:@ "User_browse"]);    Write Data sql = @ "INSERT into Test (name,image) VALUES (?,?)";    [Database executeupdate:sql,@ "Zhang San", data];    Read Show 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 queues

Database thread safety ***********//fmdatabasequeue *queue = [[Fmdatabasequeue alloc] initwithpath:[self getdatabase    Path]]; [Queue indatabase:^ (Fmdatabase *db) {//thread-safe __block nsstring *sql = @ "CREATE table if not exists Test (ID integer PRIMARY key autoincrement,na        Me text,image blob); ";    CREATE TABLE [Database Executeupdate:sql];    }];         Insert data [queue indatabase:^ (Fmdatabase *db) {//write Data sql = @ "INSERT into Test (name,image) VALUES (?,?)";    [Database executeupdate:sql,@ "Zhang San", data];    }];        Read [Queue indatabase:^ (Fmdatabase *db) {//read show 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:

。。。 _queue = Dispatch_queue_create ([[NSString stringwithformat:@ "fmdb.%@", Self] utf8string], NULL);        Dispatch_queue_set_specific (_queue, Kdispatchqueuespecifickey, (__bridge void *) self, NULL);        _openflags = Openflags;

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

Dispatch_sync (_queue, ^ () {        fmdatabase *db = [self database];        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

Appdetailmodal *newapp = [nsentitydescription insertnewobjectforentityforname:tablename inManagedObjectContext: Context];

Other query, update, delete operations
Get entity

    Nsentitydescription *entity = [nsentitydescription entityforname:tablename inmanagedobjectcontext:context];

  

2. Thread-Safe CoreData operation:

Create a parallel Nsmanagedobjectcontext object first

nsmanagedobjectcontext* Context=[[nsmanagedobjectcontext Alloc] Initwithconcurrencytype: Nsprivatequeueconcurrencytype];

  

Then use the two method:-(void) Performblock when performing a read operation: (void (^) (void)) block-(void) performblockandwait: (void (^) (void)) block

  

[Context performblock:^{        //read operation to be performed}];

  

Thread safety for CoreData and SQLite multithreaded 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.