做iphone项目半年来一直被sqlite3的多线程问题困扰,一直尝试在解决。
在项目中,我最开始使用的是sqlite3的activerecord持久化框架sqlite3persistent.framework。但是用于项目中时有以下问题:
1、在多线程查询、保存、修改数据时,经常会有sqlite3的代码执行crash掉(我没有做线程读写锁,并且对锁不熟悉)。
2、不利于大量保存数据。保存大量数据时,执行效率低,影响程序运行
3、若在主线程处理sqlite3,crash机率降低很多,但是会锁死界面。
今天测试了另一个sqlite3的框架fmdb, 发现在多线程下表现比sqlite3persistent好很多。就测试而言,未发现在多线程下的crash。
准备更改项目底层数据库代码了。。
为此问题纠结了很久,希望可以帮到有这方面需要的同学,特分享sqlite3多线程代码。FMDB代码在github上有,是开源代码。点此下载。
测试代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
opQueue = [[NSOperationQueue alloc] init];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(multiThread1:) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:0.15 target:self selector:@selector(multiThread2:) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:0.17 target:self selector:@selector(multiThread3:) userInfo:nil repeats:YES];
//[NSTimer scheduledTimerWithTimeInterval:1.3 target:self selector:@selector(multiThread4:) userInfo:nil repeats:NO];
}
- (void) multiThread1:(NSTimer *)timer
{
NSInvocationOperation * theOp1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(addObject) object:nil];
[opQueue addOperation:theOp1];
[theOp1 release];
//[timer invalidate];
}
- (void) multiThread2:(NSTimer *)timer
{
NSInvocationOperation * theOp2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(removeObject) object:nil];
[opQueue addOperation:theOp2];
[theOp2 release];
}
- (void) multiThread3:(NSTimer *)timer
{
NSInvocationOperation * theOp3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(showObject) object:nil];
[opQueue addOperation:theOp3];
[theOp3 release];
}
- (void) addObject
{
NSLog(@"---------------- addObject");
ContactDao * cdao = [[ContactDao alloc] init];
Contact * ct = [[Contact alloc] init];
ct.userid = random();
ct.friendid = random();
ct.isrecommend = random()%2;
ct.isfriend = random()%2;
NSLog(@"addObject: %d_%d", ct.userid, ct.friendid);
[cdao saveContact:ct];
[ct release];
[cdao release];
}
- (void) removeObject
{
NSLog(@"---------------- removeObject, count:%D", [list count]);
ContactDao * cdao = [[ContactDao alloc] init];
Contact * ct = [cdao findFirstByCriteria:nil];
NSLog(@"removeObject: %d_%d of index: %d", ct.userid, ct.friendid, ct.index);
if (ct.index >= 0) {
[cdao deleteAtIndex:ct.index];
}
[cdao release];
}
- (void) showObject
{
NSLog(@"---------------- showObject, count:%D", [list count]);
ContactDao * cdao = [[ContactDao alloc] init];
Contact * ct = [cdao findFirstByCriteria:nil];
NSLog(@"showObject: %d_%d", ct.userid, ct.friendid);
//[cdao deleteAtIndex:ct.index];
[cdao release];
}
BaseDao类如下:
//
// BaseDao.h
// Taonan
//
// Created by zengconggen on 11-8-30.
// Copyright 2011 yongmengsoft. All rights reserved.
//
#import <Foundation/Foundation.h>
@class FMDatabase;