后台线程

时间:2018-04-04 08:43:18

标签: ios swift fmdb

当我尝试在后台线程中读取数据库时出现问题。有几个崩溃消息,例如" EXC_BAD_INSTRUCTION",引用FMDatabase.m文件中的不同代码行,但数据库错误消息只有一个:

  

2018-04-04 09:16:17.166 MyAppName [821:12717] FMDatabase目前正在使用中。

当我在不同的ViewControllers中对我的项目进行编码时,这个消息错误一直伴随着我,直到今天我还以为我的数据库实例/选择函数已经出现了,但我发现问题是由后台线程发生的。这是我的代码的一部分。
我的数据库实例:

class func getInstance() -> DBHelper {

    let documentsFolder = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    databasePath = (documentsFolder + "/myAppName.db") as NSString
    let filemgr = FileManager.default

    if !filemgr.fileExists(atPath: databasePath as String) {

        let contactDB = FMDatabase(path: databasePath as String)

        if (contactDB.open()) {

            /*** my instructions to create an database  ***/

            contactDB.close()

        }
    } else {

        //database exist, check version and update schema
        //version number numerated from 0 (default is 0)

        let version = sharedInstance.checkVersion()
        print("version: \(version)")

        //            switch version {
        //
        //            case 0:
        //
        //                print("case 0")
        //
        //                sharedInstance.setVersion(version: Int32(dbVersion))
        //                break
        //
        //            default:
        //
        //                break
        //
        //            }

    }

    if(sharedInstance.database == nil) {

        let documentsFolder = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
        databasePath = (documentsFolder + "/myAppName.db") as NSString

        sharedInstance.database = FMDatabase(path: databasePath as String)

    }

    return sharedInstance

}

我的选择功能,通常会导致问题:

func selectAllWhere(tableName:String, whereColumns:String) -> FMResultSet {

    if sharedInstance.database!.open() {

        do {

            let querySQL = "SELECT * FROM \(tableName) WHERE \(whereColumns)"

            let result = try self.database?.executeQuery(querySQL, values: [])

            return result!

        } catch {

            print("error = \(error.localizedDescription)")
            print("error = code: \(database?.lastErrorCode()) message: \(database?.lastErrorMessage())")

            return FMResultSet()
        }

    } else {

        return FMResultSet()

    }

}

使用示例(自定义日历,应显示月,月中每天的多个事件,并使用UIPageViewController切换):

class  MonthlyCalendar: UICollectionViewController, UICollectionViewDelegateFlowLayout {

/*** collection functions and more ***/

let newInstance:DBHelper =  DBHelper.getInstance()

func setCalendarItems(month:Int) {

    DispatchQueue.global(qos: .background).async {
    //DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
    //DispatchQueue.global().async(execute: {

        let calendar = Calendar.current
        let date = calendar.date(byAdding: .month, value: page, to: start!)
        let dayRange = calendar.range(of: .day, in: .month, for: date!)
        for currentMonthDay in 0..<dayRange!.count {

            var numEvents:Int = 0
            let eventForDate = calendar.date(byAdding: .day, value: currentMonthDay, to: date!)
            let day = calendar.component(.weekday, from: eventForDate!)
            let whereStatement = " \(db.columnEventDateStart) LIKE '%\(dateFormatter.string(from: eventForDate!))%'"
            let eventQuery = self.newInstance.selectAllWhere(tableName: db.tableEvents, whereColumns: whereStatement)
            while eventQuery.next() {

                numEvents = numEvents + 1

            }

/*** instructions, when I’m adding rows to array ***/

        }

        DispatchQueue.main.sync {

            self.collectionView?.reloadData()

        }
}

这是一个问题:

  

DispatchQueue.global(qos:.background).async

我的选择查询工作正常,当我删除此行时,应用程序不会崩溃(以及负责主线程更新的代码,下面几行),但是我的代码在主线程中工作,并且当我的表中的部分数据很大时,可能会锁定/冻结它,这是不好的解决方案。问题听起来像后台操作尝试在多个线程中工作,并且当第一个线程将使用我的数据库实例时,第二个线程在数据库查询上返回异常,因为第一个线程已经忙了。如果不同,请纠正我。但是,我尝试使用不同的DispatchQueues,但是一直出现此问题。有趣的是,第一次,当我启动ViewController时,所有必需的数据都被正确读取(页面默认加载 - 3个可见页面),当我尝试左/右切换页面时,新内容导致崩溃。我无法找到解决问题的方法。以上从FMDatabase读取数据的方法以更快捷的方式呈现,我读过这些内容。请帮忙。

0 个答案:

没有答案