无法在 swift 中的解析中调用 "findObjectsInBackground"

Unable to call "findObjectsInBackground" in parse in swift

在下面的代码中,当我调用 openDatabase() 时,它显示 fatal error as 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
    }
}

想必你有这样的代码

 let x = existDatabase()
 x.openDatabase()

问题是您的初始化程序中有一个异步块,这意味着当初始化程序 returns 时对象不会被完全初始化; Parse 后台提取尚未完成。

你会崩溃,因为隐式展开的可选是 nil。您需要使用隐式展开的可选项这一事实是您的第一个警告信号。您应该能够为初始化程序中的 属性 集使用非可选值,但您不能,因为属性是在闭包中设置的。

在初始化程序中进行异步操作很少是一个好的设计。

我建议您重构代码,以便 openDatabase 执行异步操作并接受完成处理程序。

此外,从文体上来说,class 名称应以大写字母开头,并且通常是名词,而不是动词。

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
    }
}