Evo*_*Sae 5 sql iphone azure ios swift
我一直在关注成功查询表的Microsoft Azure 文档(插入,读取和更新项目到数据库工作正常),但在一个简单的方法结束时,直接关闭文档:
func getAllEventIDs() -> [String] {
var events:[String] = [] //this is to be updated
let delegate = UIApplication.sharedApplication().delegate as! AppDelegate
let client = delegate.client! //boiler-plate for azure
let itemTable = client.tableWithName("Events")
itemTable.query().readWithCompletion {
//something about this query block might be preventing successful initialization to the events array
(result:MSQueryResult!, error) in
//usually error-checking here
for item in result.items {
events.append(item.valueForKey("id") as! String)
//returning events here...
}
//...and here (almost) work, since Swift expects a return of type Void
}
return events //still empty
}
Run Code Online (Sandbox Code Playgroud)
我可能不会将数组作为参数传递,因为该.append函数将改变该数组.
返回的值只是初始的空数组.但是,这个问题似乎很大程度上源于Azure的查询代码块,而不是来自Swift本身.
func returnValueArray() -> [Int] {
var array:[Int] = [0,0,0,0]
var num:Int = 3
for var n = 0; n < array.count; n++ {
array[n] = num
}
return array
}
Run Code Online (Sandbox Code Playgroud)
返回[3,3,3,3].同样,不是Swift的问题,但Swift可能已经体现了Azure的回归问题.
如何在查询方法结束时返回所需的更新数组?是否可以将可变数组传入方法,追加值,然后返回该数组?
您问:"如何在查询方法结束时返回所需的更新数组?" 简答:你做不到.
这是异步编码的基础.
该readWithCompletion方法是异步的.它将您在后台处理的请求排队,并立即返回.
您的return events //still empty代码在读取请求开始处理之前执行.
您需要重构您的getAllEventIDs方法以将完成块作为参数.该完成块将传递给您的事件数组.然后在完成块内部为readWithCompletion您调用方法的完成块getAllEventIDs.
所以当你调用时getAllEventIDs,你会传递一个完成块来完成你需要对events数组做的事情.
我创建了一个名为SwiftCompletionHandlers的Github项目,该项目说明了这一点以及如何处理它.它有一个AsyncManager模拟异步下载的示例类.
https://github.com/DuncanMC/SwiftCompletionHandlers
它有一个如下所示的方法:
func asyncFetchImage(#imageName: String,
completion: (
image: UIImage?,
status: String) -> ())
{
println("Entering \(__FUNCTION__)")
//Simulate a network operation by waiting a few seconds
//before loading an image
let nSecDispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 *
Double(NSEC_PER_SEC)))
let queue = dispatch_get_main_queue()
dispatch_after(nSecDispatchTime, queue)
{
() -> Void in
let result = UIImage(named: imageName)
println("Loading image in background")
let status = result != nil ? "image loaded" : "Error loading image"
println("About to call completion handler")
completion(image: result, status: status)
}
println("Leaving \(__FUNCTION__)")
}
Run Code Online (Sandbox Code Playgroud)
它需要一个文件名和一个完成块.完成块传递UIImage可选和String状态消息.
下载完成后,该方法将调用完成块(也称为闭包).
以下是调用此方法的代码:
@IBAction func loadImage(sender: UIButton)
{
let theAsyncManager = AsyncManager.sharedAsyncManager
println("about to call asyncFetchImage")
theAsyncManager.asyncFetchImage(imageName: "wareto_blue_150x115")
{
(image, status) -> () in
println("Beginning completion block")
self.theImageView.image = image
println("In completion block, status = \(status)")
}
println("After call to asyncFetchImage")
}
Run Code Online (Sandbox Code Playgroud)
println语句的输出是理解正在发生的事情的关键:
about to call asyncFetchImage
Entering asyncFetchImage(imageName:completion:)
Leaving asyncFetchImage(imageName:completion:)
After call to asyncFetchImage
Loading image in background
About to call completion handler
Beginning completion block
In completion block, status = image loaded
Run Code Online (Sandbox Code Playgroud)
请注意,在"在后台加载图像"消息之前打印"Leaving asyncFetchImage"和"After call to asyncFetchImage"消息.然后是"关于调用完成处理程序",然后是"开始完成块".
因此,实际的异步工作甚至在loadImage函数返回之后才开始.
如果您不理解我所描述的内容,请下载项目并进行试用,然后设置断点并观察它的执行情况.