使实例等待,直到被调用的函数完成 - Swift

如果这已经得到回答,我会事先道歉但是你可以从标题中看出我不确定如何描述问题,我找到的类似问题的答案也没有用。

我试图在init方法中将id传递给数据库之后,创建一个“Coupon”实例,该实例的属性是从SQL数据库加载的。

我的问题是,当我从另一个viewController类调用init方法时,它将返回具有默认字符串值“”的实例,因为NSURLConnection中的数据在返回viewContoller之前尚未被/已解码。

我正在寻找一些解决方案,以使init方法等到字段加载为止。

优惠券类相关属性:

var webData: NSMutableData?

var id: Int
var name: String = ""
var provider: String = ""
var details: String = ""

优惠券类相关方法:

convenience init(id: Int) {

    self.init()
    self.id = id

    self.selectSQL(id) //passes id to server and returns all other varibles

}

   func selectSQL(id: Int) {

    let url = NSURL(string: "http://wwww.website.php?id=\(id)") // acess php page
    let urlRequest = NSURLRequest(URL: url!)
    let connection = NSURLConnection(request: urlRequest, delegate: self)

}

func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {

    webData = NSMutableData()

}

func connection(connection: NSURLConnection, didReceiveData data: NSData) {

    webData?.appendData(data)

}

func connectionDidFinishLoading(connection: NSURLConnection) {

    let result = NSJSONSerialization.JSONObjectWithData(webData!, options: .AllowFragments, error: nil) as? NSArray

    let resultDict = result?[0] as? NSDictionary

    if let dict = resultDict {

        name = dict.objectForKey("name") as! String
        provider = dict.objectForKey("provider") as! String
        details = dict.objectForKey("details") as! String

    }
采纳答案:

不能“等待你的SQL完成”然后从init返回而不阻塞你的线程(同步),这不是你想要的。

我建议使用带回调的工厂方法来获取它的解决方法。 像这样:

class Coupon {
    private var handler: ((coupon: Coupon) -> ())?

    class func createCoupon(id: Int, completionHandler: ((coupon: Coupon) -> ())?) {
        let coupon = Coupon(id: id)

        // Store the handler in coupon
        coupon.handler = completionHandler
    }

    //...

    func connectionDidFinishLoading(connection: NSURLConnection) {

        //...Setup coupon properties
        handler?(coupon: self)
        handler = nil
    }
}

然后你可以创建和使用这样的优惠券:

Coupon.createCoupon(1, completionHandler: { (coupon) -> () in
    // Do your thing with fully "inited" coupon
})

当然,您还需要考虑连接失败的情况,并且可能会调用handler时出现错误,这在当前代码中不存在。

author: onevcat

参考更多解答: Make instance wait until called functions are complete - Swift ,转载请保留出处使实例等待,直到被调用的函数完成 - Swift及作者信息

Statement: We respect knowledge and authors. Since the content comes from the Internet and is intended for scientific research, any reprinters should retain the author's signature and origin. If you are the author of the content and feel in dispute, please contact email: 1076545519@qq.com. We will find out the situation and deal with it in time. We sincerely thank the author for his hard work.


更多:init