首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Microsoft (或Swift一般)不能在表查询后更新变量以返回?

为什么Microsoft (或Swift一般)不能在表查询后更新变量以返回?
EN

Stack Overflow用户
提问于 2015-08-10 02:15:59
回答 1查看 580关注 0票数 5

我一直在跟踪Microsoft 文档成功地查询表(插入、读取和更新数据库中的项很好),但是在一个简单方法的末尾,直接从文档中:

代码语言:javascript
复制
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
}

I 可能不会将数组作为参数传递进来。,因为.append函数将对该数组进行变异。

返回的值只不过是初始的空数组。然而,这个问题似乎在很大程度上源于Azure的查询代码块,而不是Swift本身。

一个简单的例子:

代码语言:javascript
复制
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
}

这将返回3,3,3,3。同样,不是Swift的问题,但是Swift可能已经表现出Azure的返回问题。

如何在查询方法结束时返回所需的更新数组?是否可以将可变数组传递到方法中,追加值,然后返回该数组?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-10 02:52:20

您问过:“如何在查询方法结束时返回所需的更新数组?”简短的回答:你不能。

这是异步编码的基础。

readWithCompletion方法是异步的。它在后台排队处理请求,并立即返回。

在读取请求开始处理之前执行return events //still empty代码。

您需要重构您的getAllEventIDs方法以接受一个完成块作为参数。完成块将传递给您的事件数组。然后,在readWithCompletion的完成块中,您将调用getAllEventIDs方法的完成块。

因此,当您调用getAllEventIDs时,您传递给它一个完成块,用于处理事件数组所需的操作。

编辑:

我创建了一个名为SwiftCompletionHandlers的Github项目,它演示了这一点以及如何处理它。它有一个示例类AsyncManager,它模拟异步下载。

https://github.com/DuncanMC/SwiftCompletionHandlers

它的方法如下所示:

代码语言:javascript
复制
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__)")
  }

它需要一个文件名和一个完成块。完成块将被传递一个UIImage可选消息和一个字符串状态消息。

下载完成后,该方法将调用完成块(也称为闭包)。

下面是调用此方法的代码:

代码语言:javascript
复制
  @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")
  }

println语句的输出是理解所发生的事情的关键:

代码语言:javascript
复制
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

请注意,“离开asyncFetchImage”和“对asyncFetchImage的后调用”消息打印在“在后台加载图像”消息之前。然后是“即将调用完成处理程序”,然后是“开始完成块”。

因此,直到loadImage函数返回之后,实际的异步工作才会启动。

如果您不了解我描述的内容,请下载该项目并试用它,然后设置断点并查看它的执行情况。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31910771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档