当前位置:  开发笔记 > 数据库 > 正文

在iOS 4.0上使用SQLite(FMDB)和线程时的EXC_BAD_ACCESS

如何解决《在iOS4.0上使用SQLite(FMDB)和线程时的EXC_BAD_ACCESS》经验,为你挑选了1个好方法。

我正在使用FMDB处理我的数据库工作正常.该应用程序使用后台线程,它正在做一些工作,需要访问数据库.同时主线程需要在同一个数据库上运行一些查询.FMDB本身有一个小锁定系统,但是,我在我的类中添加了另一个.

只有当我的类指示数据库未使用时,才会执行每个查询.执行操作后,数据库将解锁.只要负载不是太高,这就可以正常工作.当我在主线程上运行的线程访问大量数据时,会发生EXC_BAD_ACCESS错误.

这是看起来:

- (BOOL)isDatabaseLocked {
    return isDatabaseLocked;
}

- (Pile *)lockDatabase {
    isDatabaseLocked = YES;
    return self;        
}

- (FMDatabase *)lockedDatabase {
    @synchronized(self) {
        while ([self isDatabaseLocked]) {
            usleep(20);
            //NSLog(@"Waiting until database gets unlocked...");
        }
        isDatabaseLocked = YES;
        return self.database;       
    }
}

- (Pile *)unlockDatabase {
    isDatabaseLocked = NO;
    return self;            
}

调试器说错误发生[FMResultSet next]在该行

rc = sqlite3_step(statement.statement);

我仔细检查了所有保留计数,此时所有对象都存在.同样,它只发生在主线程在后台线程运行时启动大量查询时(它本身总是产生很大的负载).错误总是由主线程产生,而不是由后台线程产生.

我的最后一个想法是两个线程同时运行lockedDatabase,这样他们就可以得到一个数据库对象.这就是我通过"@synchronized(self)"添加互斥锁定的原因.但是,这没有帮助.

有人有线索吗?



1> Rik Smith-Un..:

SQLite提供了更简单的序列化.通过设置sqlite_config()选项SQLITE_CONFIG_SERIALIZED,您可能会避免大多数这类令人头疼的问题.在与线程问题作斗争很长一段时间之后,我发现了这一点.

这是你如何使用它,你可以把它放在FMDatabase的init方法中......

    if (sqlite3_config(SQLITE_CONFIG_SERIALIZED) == SQLITE_ERROR) {
        NSLog(@"couldn't set serialized mode");
    }

有关详细信息,请参阅有关threadsafety和serialized模式的SQLite文档.

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有