使用FMDB将数据插入SQLite时,dispatch_async上的EXC_BAD_ACCESS

时间:2013-03-19 08:19:44

标签: ios objective-c ios6 thread-safety dispatch-async

所以,我已经阅读了我在互联网上发现的每一篇文章,但我仍然无法做到这一点。

我试图将大量数据插入sqlite数据库。它有20000行数据,因此我必须在后台线程中执行此操作。

我有一个NSObject .h和.m文件来处理数据库操作。我从主视图中调用它们。

这是我的代码:

SQLiteDBHandler.m :

 database = [FMDatabase databaseWithPath:[self getDBPath]];
    [database open];
    dispatch_queue_t q = dispatch_queue_create("FMDBQueue", NULL);
    dispatch_async(q, ^{
        for(Customer *c in arrayOfObjects) {
            [database executeUpdate:@"INSERT INTO SNP(rdis, Position, FirstName, LastName) VALUES (?,?,?,?)", c.ID, c.Position, c.FirstName, c.LastName];
        }
        [database close];
    });

并且为了在主视图中调用方法,我这样称呼它:

SQLiteDBHandler *dbHandler = [[SQLiteDBHandler alloc]init];

[dbHandler insertDataIntoTable:mutableArray];

我尝试用FMDatabaseQueue更改FMDatabase没有运气。所以任何帮助都会受到高度赞赏,因为我非常绝望。

感谢。干杯!

2 个答案:

答案 0 :(得分:1)

如果您两次调用InsertDataIntoTable或尝试访问数据库的任何其他方法,您可能会遇到数据库连接关闭的情况,然后才能执行查询。 请考虑以下情况:

  1. 线程1打开数据库连接
  2. 线程2打开数据库连接
  3. 线程1将一个块添加到队列
  4. 线程2将一个块添加到队列
  5. 线程1完成运行并关闭数据库连接
  6. 线程2尝试运行其块,但数据库连接已关闭。
  7. 尝试在阻止内部调用[database open]

答案 1 :(得分:0)

EXC_BAD_ACCESS表示你有一个僵尸,启用僵尸对象并使用乐器工具,它会显示僵尸对象的位置。这里的链接是一个关于如何检测它们的好教程

http://www.raywenderlich.com/2696/how-to-debug-memory-leaks-with-xcode-and-instruments-tutorial

希望有所帮助

编辑:

在xCode中,屏幕顶部的工具栏Product-> Edit Scheme-> Diagnostics->单击“启用僵尸对象”

然后在屏幕顶部的工具栏上选择产品,然后转到配置文件,仪器应该出现,你应该看到一个僵尸选项,选择它。

EDIT2:

忘了说,只有在模拟器上进行性能分析时才会出现僵尸模板,如果您尝试在实际设备上进行性能分析,它将不会出现

Edit3:Pics

enter image description here

然后你应该看到这个

enter image description here

然后当您运行应用程序时,导航到发生错误的屏幕,应用程序应该停止,这应该出现

enter image description here

单击错误消息旁边的箭头,您应该在堆栈跟踪中显示发生错误的位置