Swift如何在退出函数之前等待回调完成?

Swift如何在退出函数之前等待回调完成?,swift,callback,wait,apple-watch,Swift,Callback,Wait,Apple Watch,我在这个请求中遇到的问题是,第一个函数syncRequest总是返回nil,因为该函数在(回复,错误)返回以填写返回字典之前退出 有没有一种方法可以让它在退出我的关闭之前等待回调返回 public typealias KKWatchSyncResponse = Dictionary<String, AnyObject> func syncRequest() -> KKWatchSyncResponse? { var syncResponseDict : KKWatch

我在这个请求中遇到的问题是,第一个函数syncRequest总是返回nil,因为该函数在(回复,错误)返回以填写返回字典之前退出

有没有一种方法可以让它在退出我的关闭之前等待回调返回

public typealias KKWatchSyncResponse = Dictionary<String, AnyObject>

func syncRequest() -> KKWatchSyncResponse? {
    var syncResponseDict : KKWatchSyncResponse?
    createRequest(KKWatchRequest.Sync, parameter: nil) { reply, error in
        if reply == nil || error != nil {
            return
        } else {
            syncResponseDict = KKWatchSyncResponse()
        }
        if let songInfo = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["songInfo"] as NSData) as NSDictionary? {
            syncResponseDict!["songInfo"] = songInfo
        }
        if let albumArtImage = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["albumArt"] as NSData) as? UIImage {
            syncResponseDict!["albumArtImage"] = albumArtImage
        }
        if let isPlaying = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["isPlaying"] as NSData) as? Bool {
            syncResponseDict!["isPlaying"] = isPlaying
        }
    }()
    return syncResponseDict
}

    func createRequest(request:KKWatchRequest, parameter: KKWatchAPIRequestParameter?, callback:KKWatchAPICallback) -> KKWatchAPIParentRequest {
       var requestDict : Dictionary<String, AnyObject> = [KKBOXWatchAppRequestType : request.rawValue]
        if parameter != nil {
        requestDict += parameter! //Combine 2 dictionaries
    }
        return { WKInterfaceController.openParentApplication(requestDict){ reply, error in
                callback(reply, error)
        }
    }
}
public-typealias KKWatchSyncResponse=字典
func syncRequest()->KKWatchSyncResponse?{
var SyncResponse指令:KKWatchSyncResponse?
createRequest(KKWatchRequest.Sync,参数:nil){reply,出现错误
如果回答==nil | |错误!=nil{
返回
}否则{
syncResponseDict=KKWatchSyncResponse()
}
如果让songInfo=NSKeyedUnarchiver.unarchiveObjectWithData(回复![“songInfo”]作为NSData)作为NSDictionary{
syncResponseDict![“songInfo”]=songInfo
}
如果让albumArtImage=NSKeyedUnarchiver.unarchiveObjectWithData(回复![“albumArt”]作为NSData)作为UIImage{
syncResponseDict![“albumArtImage”]=albumArtImage
}
如果让isplay=NSKeyedUnarchiver.unarchiveObjectWithData(回复![“isplay”]为NSData)为?Bool{
syncResponseDict![“isPlaying”]=isPlaying
}
}()
返回同步命令
}
func createRequest(请求:KKWatchRequest,参数:KKWatchAPIRequestParameter?,回调:KKWatchAPICallback)->kkwatchapipparentrequest{
var requestDict:Dictionary=[KKBOXWatchAppRequestType:request.rawValue]
如果参数!=nil{
requestDict+=参数!//组合2个字典
}
返回{WKInterfaceController.openParentApplication(requestDict){reply,错误在
回调(回复,错误)
}
}
}

非常感谢你的帮助

您是否可以让
syncRequest()
执行一个闭包,该闭包在准备就绪时会被调用,并显示结果?将定义更改为类似以下内容:

func syncRequest(callback:(KKWatchSyncResponse?)->Void) { ... }
然后在
createRequest()
调用结束时,您可以调用
syncResponseDict
上的回调,因为现在它已填充了您的数据<代码>回调(syncResponseDict)

编辑:这是我想到的解决方案

func syncRequest(callback:(KKWatchSyncResponse?)->Void) {
    createRequest(KKWatchRequest.Sync, parameter: nil) { reply, error in            
        if reply == nil || error != nil {
            callback(nil)
        } else {
            var syncResponseDict : KKWatchSyncResponse? = KKWatchSyncResponse()
            if let songInfo = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["songInfo"] as NSData) as NSDictionary? {
                syncResponseDict!["songInfo"] = songInfo
            }
            if let albumArtImage = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["albumArt"] as NSData) as? UIImage {
                syncResponseDict!["albumArtImage"] = albumArtImage
            }
            if let isPlaying = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["isPlaying"] as NSData) as? Bool {
                syncResponseDict!["isPlaying"] = isPlaying
            }
            callback(syncResponseDict)
        }
    }()
}

实现一个锁定变量是很简单的。这对于执行异步网络加载的单元测试非常有用

func waitingFunction()
{
     //set a lock during your async function
     var locked = true
     RunSome.asyncFunction() { () -> Void in

       //after your sync function remove the lock
       locked = false
     })

     //wait for the async method to complete before advancing
     while(locked){wait()}

     //move on from the lock
     doMoreStuff()
}
func wait()
{
    NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeIntervalSinceNow: 1))
}

对这正是我想要的。谢谢你,先生:)太棒了。没问题。。。很高兴它有帮助。我不鼓励使用这种模式:在不同的线程上访问变量(此处
锁定
),而不进行同步是不安全的。在这里,它恰好在强顺序CPU(Intel)上工作,但在ARM上可能会失败。对于单元测试,我们在XCTest中有一个健壮的方法,它具有专门针对该用例的期望。