Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 我想从闭包中提取值(Swift4)_Ios_Swift_Xcode - Fatal编程技术网

Ios 我想从闭包中提取值(Swift4)

Ios 我想从闭包中提取值(Swift4),ios,swift,xcode,Ios,Swift,Xcode,我在结束时把替换的序列带了出来,但是我该怎么办呢? “startTimeArrForStart”, “endTimeArrForStart”, “返回”内容时,“scheduleArrForStart”将变为空 func getScheduleDate(date: Any) -> ([Any], [Any], [Any]) { var startTimeArrForStart = [Any]() var endTimeArrForStart = [Any]() v

我在结束时把替换的序列带了出来,但是我该怎么办呢? “startTimeArrForStart”, “endTimeArrForStart”, “返回”内容时,“scheduleArrForStart”将变为空

func getScheduleDate(date: Any) -> ([Any], [Any], [Any]) {

    var startTimeArrForStart = [Any]()
    var endTimeArrForStart = [Any]()
    var scheduleArrForStart = [Any]()

    self.db.collection("users").document(fireAuthUID).addSnapshotListener { (snapshot, error) in
        guard let document = snapshot else {
            print("erorr2 \(String(describing: error))")
            return
        }
        guard let data = document.data() else { return }
        self.teamIDFromFirebase = data["teamID"] as? String ?? ""
        self.db
            .collection("teams")
            .document(self.teamIDFromFirebase)
            .collection("schedule")
            .whereField("date_start", isEqualTo: date)
            .getDocuments() { (querySnapshot, err) in
            if err != nil {
                print("scheduleを取得できませんでした")
                return
            } else {
                for document in querySnapshot!.documents {
                    guard let dataFromFirebase: [String : Any] = document.data() else { return }
                    let startTimeFromFirebase = dataFromFirebase["date_start"] ?? ""
                    let endTimeFromFirebase = dataFromFirebase["date_end"] ?? ""
                    let scheduleFromFirebase = dataFromFirebase["event_title"] ?? ""
                    startTimeArrForStart.append(startTimeFromFirebase)
                    endTimeArrForStart.append(endTimeFromFirebase)
                    scheduleArrForStart.append(scheduleFromFirebase)
                    self.tableView.reloadData()
                }
            }
        }
    }
    print(startTimeArrForStart) //<- empty
    print(endTimeArrForStart) //<- empty
    print(scheduleArrForStart) //<- empty
    return (startTimeArrF`enter code here`orStart, endTimeArrForStart, scheduleArrForStart)
}
func getScheduleDate(日期:任意)->([Any]、[Any]、[Any]){
var startTimeArrForStart=[Any]()
var endTimeArrForStart=[Any]()
var scheduleArrForStart=[Any]()
self.db.collection(“users”).document(fireAuthUID).addSnapshotListener{(快照,错误)位于
guard let document=snapshot else{
打印(“erorr2\(字符串(描述:错误)))
返回
}
guard let data=document.data()else{return}
self.teamIDFromFirebase=数据[“teamID”]作为?字符串??“
self.db
.收集(“团队”)
.document(self.teamIDFromFirebase)
.收款(“附表”)
.whereField(“开始日期”,isEqualTo:date)
.getDocuments(){(querySnapshot,err)位于
如果错误!=零{
打印时间表を取得できませんでした")
返回
}否则{
用于querySnapshot!.documents中的文档{
guard let dataFromFirebase:[String:Any]=document.data()else{return}
让startTimeFromFirebase=dataFromFirebase[“开始日期”]??“
让endTimeFromFirebase=dataFromFirebase[“日期\结束”]??“
让scheduleFromFirebase=dataFromFirebase[“事件标题”]??“
startTimeArrForStart.append(startTimeFromFirebase)
endTimeArrForStart.append(endTimeFromFirebase)
scheduleArrForStart.append(scheduleFromFirebase)
self.tableView.reloadData()
}
}
}
}

print(startTimeArrForStart)/闭包不能保证在执行print语句或函数中的return语句之前更新捕获的变量

func getScheduleDate(date: Any, completion: (([Any], [Any], [Any]) -> Void)) ->  {

    var startTimeArrForStart = [Any]()
    var endTimeArrForStart = [Any]()
    var scheduleArrForStart = [Any]()

    self.db.collection("users").document(fireAuthUID).addSnapshotListener { (snapshot, error) in
        guard let document = snapshot else {
            print("erorr2 \(String(describing: error))")

            completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
            return
        }
        guard let data = document.data() else {
            completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
            return
        }
        self.teamIDFromFirebase = data["teamID"] as? String ?? ""
        self.db
            .collection("teams")
            .document(self.teamIDFromFirebase)
            .collection("schedule")
            .whereField("date_start", isEqualTo: date)
            .getDocuments() { (querySnapshot, err) in
                if err != nil {
                    print("scheduleを取得できませんでした")
                    completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
                    return
                } else {
                    for document in querySnapshot!.documents {
                        guard let dataFromFirebase: [String : Any] = document.data() else { return }
                        let startTimeFromFirebase = dataFromFirebase["date_start"] ?? ""
                        let endTimeFromFirebase = dataFromFirebase["date_end"] ?? ""
                        let scheduleFromFirebase = dataFromFirebase["event_title"] ?? ""
                        startTimeArrForStart.append(startTimeFromFirebase)
                        endTimeArrForStart.append(endTimeFromFirebase)
                        scheduleArrForStart.append(scheduleFromFirebase)
                        self.tableView.reloadData()
                    }
                    completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
                }
        }
    }
}
由于这3个数组仅在
addSnapshotListener
闭包内变异,因此在返回时不会有更新的值,因为当代码到达return语句时闭包尚未更新值

要获得这些数组的更新值,必须依赖闭包将值发送回函数的调用方

func getScheduleDate(date: Any, completion: (([Any], [Any], [Any]) -> Void)) ->  {

    var startTimeArrForStart = [Any]()
    var endTimeArrForStart = [Any]()
    var scheduleArrForStart = [Any]()

    self.db.collection("users").document(fireAuthUID).addSnapshotListener { (snapshot, error) in
        guard let document = snapshot else {
            print("erorr2 \(String(describing: error))")

            completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
            return
        }
        guard let data = document.data() else {
            completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
            return
        }
        self.teamIDFromFirebase = data["teamID"] as? String ?? ""
        self.db
            .collection("teams")
            .document(self.teamIDFromFirebase)
            .collection("schedule")
            .whereField("date_start", isEqualTo: date)
            .getDocuments() { (querySnapshot, err) in
                if err != nil {
                    print("scheduleを取得できませんでした")
                    completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
                    return
                } else {
                    for document in querySnapshot!.documents {
                        guard let dataFromFirebase: [String : Any] = document.data() else { return }
                        let startTimeFromFirebase = dataFromFirebase["date_start"] ?? ""
                        let endTimeFromFirebase = dataFromFirebase["date_end"] ?? ""
                        let scheduleFromFirebase = dataFromFirebase["event_title"] ?? ""
                        startTimeArrForStart.append(startTimeFromFirebase)
                        endTimeArrForStart.append(endTimeFromFirebase)
                        scheduleArrForStart.append(scheduleFromFirebase)
                        self.tableView.reloadData()
                    }
                    completion(startTimeArrForStart, endTimeArrForStart, scheduleArrForStart)
                }
        }
    }
}
使用以下命令从更新的函数中获取值:

getScheduleDate(date: Date()) { (startTime, endTime, scheduledList) in

    // Update your UI or do any actions based on the fetched data here.
}

您需要了解闭包是如何工作的

self.db.collection("users").document(fireAuthUID).addSnapshotListener { 
    // this section is 'separate' from the code around
    // usually these callbacks (addSnapshotListener) get to be called later on        
}
这里有一个方法可以帮助您

func doSomethingAfterGettingInfoFor(date: Any) { // rename to understand better func getScheduleDate(date: Any) {
        self.db.collection("users").document(fireAuthUID).addSnapshotListener { [weak self] (snapshot, error) in // <- do not create leaks
        self.doSomethingLaterOnWith(snapshot, and: error, calledFor: date)
    }
}
现在你可以做一些事情,比如:

 func someImplementation() {
        doSomethingAfterGettingInfoFor(date: Date())   // << -- see from above 
    }

    func doSomethingLaterOnWith(snapshot: SnapshotType, and error: ErrorType, calledFor: Date) {
        // and here you were doing something depending on the result


         guard let document = snapshot else {
                print("erorr2 \(String(describing: error))")
                return
            }
            guard let data = document.data() else { return }
            self.teamIDFromFirebase = data["teamID"] as? String ?? ""
            self.db
                .collection("teams")
                .document(self.teamIDFromFirebase)
                .collection("schedule")
                .whereField("date_start", isEqualTo: date)
                .getDocuments() { (querySnapshot, err) in
                if err != nil {
                    print("scheduleを取得できませんでした")
                    return
                } else {
                    for document in querySnapshot!.documents {
                        guard let dataFromFirebase: [String : Any] = document.data() else { return }
                        let startTimeFromFirebase = dataFromFirebase["date_start"] ?? ""
                        let endTimeFromFirebase = dataFromFirebase["date_end"] ?? ""
                        let scheduleFromFirebase = dataFromFirebase["event_title"] ?? ""
                        startTimeArrForStart.append(startTimeFromFirebase)
                        endTimeArrForStart.append(endTimeFromFirebase)
                        scheduleArrForStart.append(scheduleFromFirebase)
                        self.tableView.reloadData()
                    }
                }
            }


        print(previousExpectedResults.0)
        print(previousExpectedResults.1)       
    }
func someImplementation(){

doSomethingAfterGettingInfoFor(date:date())//为了简单起见,我建议编写最少的代码来显示您的问题……您缺少的概念是“异步的”。如果您检查正确,您将看到
print(“计划”)を取得できませんでした“
是在
print(startTimeArrForStart)
之后打印的。你正在与强大的类型系统作斗争。不要这样做!所有三个数组都有不同的类型,而不是
任何一个
。你为什么要使用多个数组。这是另一个坏习惯。我不太明白。self.dosomethinglateron是怎么回事(snapshot,and:error,calledFor:date)?您需要在类中实现此方法并处理来自db的响应。我将更新示例以帮助您理解。:)更新,我希望您更好地理解它(但我不确定响应的第二部分是否有效,它只是帮助您理解需要更改的内容