【问题标题】:Wait for async function return value in swift快速等待异步函数返回值
【发布时间】:2016-01-18 18:11:27
【问题描述】:

我想从 Parse 中检索用户分数并将其分配给一个变量。此函数在查询完成之前返回 0。我在Retrieve object from parse.com and wait with return until data is retrieved 找到了类似的答案。但是,我希望该函数有一个返回值,以及在调用此函数时我应该为完成处理程序使用什么参数。任何帮助将不胜感激,谢谢!

这是我的代码

func loadCurrentUserData() -> Int {
        let query = PFQuery(className: "userScore")
        let userId = PFUser.currentUser()!
        var currentUserScore: Int = 0

        query.whereKey("user", equalTo: userId)
        query.findObjectsInBackgroundWithBlock {
        (objects: [PFObject]?, error: NSError?) -> Void in
        if error == nil {
            let scoreReceived = objects![0]["score"] as! Int
            currentUserScore = scoreReceived
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
            self.userScore.text = "\(scoreReceived)"
            })
        } else {
            print("Error: \(error!) \(error!.userInfo)")
            }
        }
        return currentUserScore
    }

【问题讨论】:

  • 我尝试添加信号量。 let semaphore = dispatch_semaphore_create(0)dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)。但是还是不行。

标签: ios swift asynchronous


【解决方案1】:

您设置此函数的方式将不起作用,因为查询方法是异步的。这可以通过两种方式解决:

1) 使用 PFQuery 同步类: http://parse.com/docs/ios/api/Categories/PFQuery(Synchronous).html

这种方法的唯一缺点是该方法将成为阻塞,因此请确保从后台线程调用它。

2) 重构函数以使用完成块而不是返回值..即:

    func loadCurrentUserData(completion: (score: Int!, error: NSError?) ->()) {
            let query = PFQuery(className: "userScore")
            let userId = PFUser.currentUser()!
            var currentUserScore: Int = 0

            query.whereKey("user", equalTo: userId)
            query.findObjectsInBackgroundWithBlock {
            (objects: [PFObject]?, error: NSError?) -> Void in
            if error == nil {
                let scoreReceived = objects![0]["score"] as! Int
                currentUserScore = scoreReceived
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.userScore.text = "\(scoreReceived)"
                })
                completion(score: currentUserScore, error: nil);
            } else {
                print("Error: \(error!) \(error!.userInfo)")
                }
                completion(score: currentUserScore, error: error);

            }
        }

【讨论】:

  • 谢谢约翰,但是以后如何调用这个函数。如果我想稍后将 currentUserScore 传递给其他函数怎么办?
  • 现在看起来不错!我会在不久之后删除我的 cmets,并且还会投票。感谢您考虑改进。
猜你喜欢
  • 2020-12-23
  • 2020-03-13
  • 2011-03-04
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
  • 2013-07-24
相关资源
最近更新 更多