我正在编写使用此项目的IOS应用程序:https://github.com/martinrybak/SQLClient。我在使用下面的代码与SQL通信时遇到问题。它不会在第一次遇到连接功能时执行。它转到下一行,在viewDidLoad中生成所有代码后,它返回到我的connect方法,连接成功。如何让它首先执行代码和之前的所有其他代码?是不是快速和ios编程的东西我还不明白?
override func viewDidLoad() {
super.viewDidLoad()
let client = SQLClient.sharedInstance()
client?.connect(Constants.serwerAdress, username: Constants.userName, password: Constants.password, database: Constants.databaseName) {
success in
if success {
client?.execute("select A FROM B") {
results in
for table in results as AnyObject! as! NSArray {
for row in table as AnyObject! as! NSArray {
for column in row as! NSDictionary {
print("\(column.key) = \(column.value)")
}
}
}
client?.disconnect()
}
}
}
DoSomethingElse()
}
答案 0 :(得分:1)
移动DoSomethingElse
以连接成功结束。
override func viewDidLoad() {
super.viewDidLoad()
let client = SQLClient.sharedInstance()
client?.connect(Constants.serwerAdress, username: Constants.userName, password: Constants.password, database: Constants.databaseName) {
success in
if success {
client?.execute("select A FROM B") {
results in
for table in results as AnyObject! as! NSArray {
for row in table as AnyObject! as! NSArray {
for column in row as! NSDictionary {
print("\(column.key) = \(column.value)")
}
}
}
client?.disconnect()
DoSomethingElse()
}
}
}
}
代码中的方法如connect,execute将closure作为参数。这清楚地表明这些函数本质上是异步的,并且将异步执行args。很明显,一旦连接完成执行,你就无法将它写为连接和执行的下一行。
修改强>
在connect / execute中调用DoSomethingElse()是处理这种情况的唯一方法吗?不。
考虑我可以考虑哪些可能的解决方案:
您可以使用KVO
。 :当连接/执行更新可以调用DoSomethingElse的数据源时,将观察者设置为数据源。如果你问我,我更喜欢更清洁的方法:)
使用Semaphores
或dispatch_semaphores
(与信号量相比更好)来阻止线程:根本不是建议的解决方案!!使用semaphore/dispatch_semaphores
阻止主线程可能会导致iOS因为无响应而终止您的应用,并可能提供最差的用户体验。
使用Dispatch_Group
:Dispatch_Group用于监视独立块的完成情况。这可以考虑。但我更喜欢从闭包内部调用方法。保持代码清洁:)