我提前道歉,如果这已经得到了回答,但你可以从标题中看出我不确定如何描述问题,我找到的类似问题的答案也无济于事。
我正在尝试在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
}
答案 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
并显示错误,而该错误在当前代码中不存在。