我正在努力了解GCD,特别是DispatchGroup,以通过FMDB包装器将下载组织到SQLite数据库中。我的应用程序执行以下操作:
wait(timeout:)
函数。但是,在实现DispatchGroup时(如下所示),我收到以下错误。
API call with NULL database connection pointer [logging] misuse at line 125820 of [378230ae7f]
还有
BUG IN CLIENT OF libsqlite3.dylib: illegal multi-threaded access to database connection
代码如下:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Download from server
if availableSubjects[indexPath.row].isDownloaded == 0 {
//CHAINING THIS WAY WORKS
/* downloadModel.downloadCaseBundle(withSubjectID: indexPath.row, completion: {
self.downloadModel.downloadToken(forSubject: indexPath.row, completion: {
self.caseBundle = DBManager.sharedDBManager.getCaseBundle(forSubject: indexPath.row)
self.availableSubjects[indexPath.row].isDownloaded = 1
DispatchQueue.main.async {
self.performSegue(withIdentifier: "showCaseList", sender: self)
}
})
})*/
let dispatchGroup = DispatchGroup()
//Download content
dispatchGroup.enter()
downloadModel.downloadCaseBundle(withSubjectID: indexPath.row) {
dispatchGroup.leave()
}
//Download token
dispatchGroup.enter()
downloadModel.downloadToken(forSubject: indexPath.row) {
dispatchGroup.leave()
}
//Execute
dispatchGroup.notify(queue: .main) {
self.caseBundle = DBManager.sharedDBManager.getCaseBundle(forSubject: indexPath.row)
self.availableSubjects[indexPath.row].isDownloaded = 1
self.performSegue(withIdentifier: "showCaseList", sender: self)
}
} else { //Already downloaded, just retrieve from local db and present
caseBundle = DBManager.sharedDBManager.getCaseBundle(forSubject: indexPath.row)
self.performSegue(withIdentifier: "showCaseList", sender: self)
}
}
downloadToken函数或多或少相同
func downloadCaseBundle(withSubjectID subjectID: Int, completion: @escaping () -> Void) { let urlPath = "someStringtoRemoteDB" let url: URL = URL(string: urlPath)! let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default) let task = defaultSession.dataTask(with: url) { (data, response, error) in if error != nil { print("Error") } else { print("cases downloaded") self.parseCasesJSON(data!, header: self.remoteMasterTable, forSubject: subjectID) completion() } } task.resume() }
下载模式,parseJSON
func parseCasesJSON(_ data:Data, header: String, forSubject subjectID: Int) {
var jsonResult = NSArray()
var jsonElement = NSDictionary()
let cases = NSMutableArray()
do {
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError {
print(error)
print("error at serialisation")
}
//Iterate through JSON result (i.e. case), construct and append to cases array
for i in 0 ..< jsonResult.count {
jsonElement = jsonResult[i] as! NSDictionary
var caseObject = CaseModel()
//The following insures none of the JsonElement values are nil through optional binding
if let uniqueID = jsonElement["id"] as? Int,
let subjectTitle = jsonElement["subjectTitle"] as? String,
let subjectID = jsonElement["subjectID"] as? Int,
let questionID = jsonElement["questionID"] as? Int,
//And so on
{
caseObject.uniqueID = uniqueID
caseObject.subjectTitle = subjectTitle
caseObject.subjectID = subjectID
caseObject.questionID = questionID
//And so on
}
cases.add(caseObject)
}
DBManager.sharedDBManager.saveCasesLocally(dataToSave: cases as! [CaseModel])
DBManager.sharedDBManager.setSubjectAsDownloaded(forSubjectID: subjectID)
}
我正在努力了解GCD,特别是DispatchGroup,以通过FMDB包装器将下载组织到SQLite数据库中。我的应用程序执行以下操作:从以下位置下载可用主题的信息:...
结果与这些方法无关,我需要在我的FMDatabaseQueue
单例中实现FMDatabase
而不是DBManager
。>