objective c - Crashes when copying SQLite db from bundle to documents and then querying -
this makes absolutely no sense (to me).
sqlite throw exc_bad_access
errors randomly (on sqlite3_prepare_v2
line in db class) when querying when copy database bundle documents folder in background thread. but, if don't perform in background thread no crashes ever occur.
the reason want perform operation in thread is quite large (~150mb).
my didfinishlaunchingwithoptions
looks - working script commented out below gcd thread:
- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions { dispatch_queue_t setupdb = dispatch_queue_create("setupdb", null); dispatch_async(setupdb, ^{ [db setup]; dispatch_async(dispatch_get_main_queue(), ^{ [db connect]; [[nsnotificationcenter defaultcenter] postnotificationname:@"databaseready" object:nil]; }); }); // if using code, though, works fine // [db setup]; // [db connect]; // [[nsnotificationcenter defaultcenter] postnotificationname:@"databaseready" object:nil]; return yes; }
the database class looks (_statement
defined in .h
):
@implementation db static sqlite3 * _db; static nsstring * _dbpath; + (bool)setup { nsstring * sqlbundlepath = [[nsbundle mainbundle] pathforresource:@"db" oftype:@"sqlite"]; nsstring * documentsfolder = nssearchpathfordirectoriesindomains(nsdocumentdirectory, nsuserdomainmask, yes)[0]; nsstring * sqldocumentpath = [[documentsfolder stringbyappendingpathcomponent:@"db"] stringbyappendingpathextension:@"sqlite"]; nsfilemanager * filemanager = [nsfilemanager defaultmanager]; // make sure don't have database in our documents, don't want overwrite! if (! [filemanager fileexistsatpath:sqldocumentpath]) { bool success = [filemanager copyitematpath:sqlbundlepath topath:sqldocumentpath error:nil]; if (! success) { nslog(@"error copying database"); return no; } } _dbpath = sqldocumentpath; return yes; } + (bool)connect { sqlite3_config(sqlite_config_serialized); sqlite3_open([_dbpath utf8string], &_db); return yes; } - (bool)prepare:(const char *)sql { if (! sqlite3_prepare_v2(_db, sql, -1, &_statement, null) == sqlite_ok) { nslog(@"error whilst preparing query: %s", sqlite3_errmsg(_db)); sqlite3_finalize(_statement); return no; } return yes; } - (bool)step { if (sqlite3_step(_statement) == sqlite_row) { return yes; } return no; } - (void)finalise { sqlite3_finalize(_statement); } @end
Comments
Post a Comment