在我的以下代码中,当我调用 openDatabase()时,由于 pathToDatabase 为零,它显示了致命错误。
实际上,当我致电 findObjectsInBackground 时,我无法进入该区块。这样我将 pathToDatabase 设置为nil?请帮我。
import UIKit
import Parse
class existDatabase: NSObject {
var databaseFileName = ""
var pathToDatabase: String!
var database: FMDatabase!
var userAccessCode = ""
override init()
{
super.init()
if let accesscode = USERDEFAULTS.string(forKey: "UserAccessCode"){
let query: PFQuery = PFQuery(className: "AccessCode")
query.whereKey("RegisterCode", equalTo: accesscode)
query.findObjectsInBackground { (objects, err) in
if err == nil{
if let users = objects{
if users.isEmpty {
}
else{
for post in users{
if let surgery = post["SurgeryType"] as? String{
if surgery == "Trigger Finger"{
self.databaseFileName = "thumbtriggerfinger"
self.pathToDatabase = Bundle.main.path(forResource: "thumbtriggerfinger", ofType: "db")
}
}
}
}
}
}
else{
print(err?.localizedDescription)
}
}
}
}
func openDatabase() -> Bool {
if database == nil {
if FileManager.default.fileExists(atPath: pathToDatabase) {
database = FMDatabase(path: pathToDatabase)
}
}
if database != nil {
if database.open() {
return true
}
}
return false
}
}
答案 0 :(得分:0)
大概您有类似的代码
let x = existDatabase()
x.openDatabase()
问题是初始化器中有一个异步块,这意味着初始化器返回时不会完全初始化对象。解析后台抓取尚未完成。
您会崩溃,因为隐式解开的可选内容是nil
。您需要使用隐式展开的可选内容是您的第一个警告信号。您应该可以对初始化程序中设置的属性使用非可选属性,但不能使用,因为这些属性是在闭包中设置的。
在初始化程序中进行异步操作很少是一个好的设计。
我建议您重组代码,以便openDatabase
执行异步操作并接受完成处理程序。
从风格上讲,类名也应该以大写字母开头,并且通常是名词,而不是动词。
class DatabaseManager {
static database(for accessCode: String, completion: @escaping (FMDatabase?,Error?)) {
let query: PFQuery = PFQuery(className: "AccessCode")
query.whereKey("RegisterCode", equalTo: accessCode)
query.findObjectsInBackground { (objects, err) in
if err == nil{
if let users = objects, !users.isEmpty {
for post in users{
if let surgery = post["SurgeryType"] as? String{
if surgery == "Trigger Finger"{
let pathToDatabase = Bundle.main.path(forResource: "thumbtriggerfinger", ofType: "db")
if FileManager.default.fileExists(atPath: pathToDatabase) {
database = FMDatabase(path: pathToDatabase)
if database.open() {
completion(database,nil)
} else {
completion(nil, nil)
}
break
}
}
}
}
} else {
completion(nil,nil)
}
}
else{
completion(nil, err)
}
}
}
}
使用以下方式调用它:
if let accesscode = USERDEFAULTS.string(forKey: "UserAccessCode"){
DatabaseManager.database(for: accesscode) { (database, error) in {
guard error == nil else {
print("error: (error!.localalizedDescription)")
return
}
guard let db = database else {
print("No database")
return
}
// Do something with db
}
}