让实例等待调用的函数完成 - Swift
Make instance wait until called functions are complete - Swift
如果这个问题已经得到解答,我提前道歉,但正如您可能从标题中看出的那样,我不太确定如何描述这个问题,而且我发现对类似问题的回答也没有帮助。
我试图创建一个 "Coupon" 的实例,在将 id 传递给 init 方法中的数据库后,它的属性从 SQL 数据库加载。
我的问题是,当我从另一个 viewController class 调用 init 方法时,它将 return 具有默认字符串值 "" 的实例作为来自 NSURLConnection 的数据在 return 进入 viewContoller 之前 been/decoded。
我正在寻找一种解决方案,以解决如何使 init 方法等待字段加载完毕的问题。
优惠券class相关属性:
var webData: NSMutableData?
var id: Int
var name: String = ""
var provider: String = ""
var details: String = ""
优惠券class相关方法:
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
}
不可能从 init
"wait for your SQL finishing" 然后 return 不阻塞你的线程(同步),这不是你想要的。
我建议使用带有回调的工厂方法来解决它。像这样:
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
会报错,而你现在的代码不会出现这种情况。
如果这个问题已经得到解答,我提前道歉,但正如您可能从标题中看出的那样,我不太确定如何描述这个问题,而且我发现对类似问题的回答也没有帮助。
我试图创建一个 "Coupon" 的实例,在将 id 传递给 init 方法中的数据库后,它的属性从 SQL 数据库加载。
我的问题是,当我从另一个 viewController class 调用 init 方法时,它将 return 具有默认字符串值 "" 的实例作为来自 NSURLConnection 的数据在 return 进入 viewContoller 之前 been/decoded。
我正在寻找一种解决方案,以解决如何使 init 方法等待字段加载完毕的问题。
优惠券class相关属性:
var webData: NSMutableData?
var id: Int
var name: String = ""
var provider: String = ""
var details: String = ""
优惠券class相关方法:
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
}
不可能从 init
"wait for your SQL finishing" 然后 return 不阻塞你的线程(同步),这不是你想要的。
我建议使用带有回调的工厂方法来解决它。像这样:
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
会报错,而你现在的代码不会出现这种情况。