Swift函数不会很快返回

时间:2015-11-05 17:16:15

标签: ios swift model-view-controller parse-platform

我试图将我的应用程序移动到MVC,我有一个Parse查询,我已经转移到我的模型类中的函数,该函数返回一个Bool。

当按下我的ViewController中的按钮时,模型函数' parseQuery'应该运行,返回一个bool然后我需要使用该bool继续。目前,if语句在函数完成之前执行,因此它始终检测为false。

如何在函数完成后确保if语句完成?

@IBAction func showAllExpiredUsers(sender: AnyObject) {

    var success = searchResults.parseQuery()

    if success {
        print("true")
    } else {
        print("false")
    }
    //I have also tried:

    searchResults.parseQuery()

    if searchResults.parseQuery() {
        print("true")
    } else {
        print("false")
    }

2 个答案:

答案 0 :(得分:0)

查询可能需要一些时间才能运行,并且应该在具有回调函数的后台线程中运行,以便在完成时处理响应。

查看Documentation

专门查看query.findObjectsInBackgroundWithBlock代码:

var query = PFQuery(className:"GameScore")
query.whereKey("playerName", equalTo:"Sean Plott")
query.findObjectsInBackgroundWithBlock {
  (objects: [PFObject]?, error: NSError?) -> Void in

  if error == nil {
    // The find succeeded.
    print("Successfully retrieved \(objects!.count) scores.")
    // Do something with the found objects
    if let objects = objects as? [PFObject] {
      for object in objects {
        print(object.objectId)
      }
    }
  } else {
    // Log details of the failure
    print("Error: \(error!) \(error!.userInfo!)")
  }
}

上面的代码将执行查询并在从Parse获取结果时运行块中的代码。这称为异步任务,有关详细信息,请查看this guide

答案 1 :(得分:0)

您有几个选项,但问题是异步调用。

Parse是否使用完成块公开相同的函数?

如果是,则将Bool的处理放在completlion块中,该块在异步任务完成时调用。

如果不是,我怀疑,您可以创建一个NSOperationQueue,其maxConcurrency为1(因此它是串行的)并使用

将调用分派到队列中

func addOperationWithBlock(_ block: () -> Void)

在队列中调用此方法。您需要全局存储成功bool,以便可以在第二个排队块操作中访问它,以检查成功状态。

<强>更新

我没有使用解析,但检查findObjectsInBackgroundWithBlock(https://parse.com/docs/ios/guide#queries)的文档,它需要一个完成块,您可以在其中处理结果,更新您的bool。

我不确定你要做什么。您不需要具有查询的成功状态。你可以检查

if (!error) { 
   // do stuff 
} else { 
  //error occured - print("error \(error.localizedDescription)"
}

检查示例。

您需要了解的是线程。异步任务提供了一个完成块,因为它是异步的,它被调度到另一个线程进行处理。我不确定您对线程有多了解,但有一些称为线程池的东西。队列访问此线程池。线程池由OS管理,并确保可用线程可由需要完成工作的队列使用。当用户与应用程序交互时,此(以及所有UI工作)在主线程上完成。

因此,只要某些处理会干扰可能的交互或UI更新,就应该从主线程调度(Grand Central Dispatch)或排队(NSOperationQueue,构建在GCD之上)。

无论如何,这就是为什么findObjectsInBackgroundWithBlock调用是从主线程调出的原因,因为否则它会阻塞主线程直到完成,从而破坏了用户的体验。此外,如果主线程被阻止超过1分钟(我上次检查),操作系统的监视器将终止您的进程。

所以是的,为块的返回分配一个布尔值将得到函数的返回,这发生在完成块完成之前。完成块是您在函数完成后编写一些要完成的事情的地方。因此,queury被调度到另一个线程并开始处理,发送此工作以进行处理的线程继续执行其余的操作。因此,直接检查布尔值,将无法工作,因为另一个线程不完整。即使其他线程及时完成,后台线程与主线程连接的是什么?

这是块(功能指针)之美,它更清洁和优化,并保持代码紧凑。旧方法仍然用于一些较旧的框架,是委托,它使用回调分离调用代码并添加委托依赖。街区很漂亮。

同样重要的是要注意,在主线程上不会总是调用完成块。在许多情况下,由您决定将工作分配回主线程,以处理需要使用完成块内可用对象完成的任何UI工作。