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

时间:2015-07-08 02:34:28

标签: ios swift init

我提前道歉,如果这已经得到了回答,但你可以从标题中看出我不确定如何描述问题,我找到的类似问题的答案也无济于事。

我正在尝试在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

    }

1 个答案:

答案 0 :(得分:4)

不可能等待你的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并显示错误,而该错误在当前代码中不存在。