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