I'm using Swift and I'm trying to append a Parse Query's results to an array, however, the array only shows the appended value when it's printed within the query's for loop. When I try printing the array outside of the loop before the method's return, I get an empty array. How can I get the array with the appended value to show outside of the for loop?
我正在使用Swift,并试图将解析查询的结果追加到一个数组中,但是,该数组只显示在查询的for循环中打印时附加的值。当我尝试在方法返回之前在循环外打印数组时,我得到一个空数组。如何使用append值来显示for循环之外的数组?
class Task {
func all() -> Array<String> {
var taskArray = Array<String>()
var query = PFQuery(className:"Task")
var currentUser = PFUser.currentUser() // this will now be nil
let userId = currentUser?.objectId
query.whereKey("userId", equalTo: currentUser!)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
println("Successfully retrieved \(objects!.count) tasks.")
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
// println(object.objectId)
let title = object["title"]! as! String
taskArray.append(title)
println("Array: \(taskArray)")
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}
println("Outside query array: \(taskArray)")
return taskArray
}
}
It looks like the outside query is being called before the query or something along the lines of that. Debug console:
它看起来就像在查询之前调用外部查询或类似的东西。调试控制台:
1 个解决方案
#1
0
As you said, the println("Outside query array: \(taskArray)")
is called before println("Array: \(taskArray)")
and there is a simple explanation to this.
正如您所说的,println(“外部查询数组:\(taskArray)”)在println(“数组:\(taskArray)”)之前被调用,这里有一个简单的解释。
findObjectsInBackgroundWithBlock
is an asynchronous method, which means that it starts another thread and works on this one. This means that the moment you call findObjectsInBackgroundWithBlock
, then it continues directly to println("Outside query array: \(taskArray)")
.
findObjectsInBackgroundWithBlock是一个异步方法,这意味着它启动另一个线程并在这个线程上工作。这意味着当您调用findObjectsInBackgroundWithBlock时,它会继续直接到println(“外部查询数组:\(taskArray)”)。
Now, it is possible to download stuff from Parse synchronously (so it will not skip directly to println("Outside query array: \(taskArray)")
), but I will not recommend you to do this.
现在,可以同步地下载解析的内容(因此它不会直接跳转到println(“外部查询数组:\(taskArray)”),但是我不会建议您这样做。
Instead I will recommend that you implement a closure which is called when the download is finished. Something similar to the following (PS, it's been written in Swift 2):
相反,我建议您实现一个闭包,在下载完成时调用该闭包。类似如下(PS,它是在Swift 2中写的):
//
// ViewController.swift
// ParseFun
//
// Created by Stefan Veis Pennerup on 21/09/15.
// Copyright (c) 2015 Kumuluzz. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
// MARK: - Lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
all { (tasks) -> Void in
print("The downloaded tasks are: \(tasks)")
}
}
// MARK: - Download methods
func all(completionHandler: ([String])->Void) {
// Creates the query
var taskArray = Array<String>()
let query = PFQuery(className:"Task")
let currentUser = PFUser.currentUser() // this will now be nil
query.whereKey("userId", equalTo: currentUser!)
// Starts the download
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) tasks.")
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
let title = object["title"]! as! String
taskArray.append(title)
print("Array: \(taskArray)")
}
}
completionHandler(taskArray)
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
}
}
#1
0
As you said, the println("Outside query array: \(taskArray)")
is called before println("Array: \(taskArray)")
and there is a simple explanation to this.
正如您所说的,println(“外部查询数组:\(taskArray)”)在println(“数组:\(taskArray)”)之前被调用,这里有一个简单的解释。
findObjectsInBackgroundWithBlock
is an asynchronous method, which means that it starts another thread and works on this one. This means that the moment you call findObjectsInBackgroundWithBlock
, then it continues directly to println("Outside query array: \(taskArray)")
.
findObjectsInBackgroundWithBlock是一个异步方法,这意味着它启动另一个线程并在这个线程上工作。这意味着当您调用findObjectsInBackgroundWithBlock时,它会继续直接到println(“外部查询数组:\(taskArray)”)。
Now, it is possible to download stuff from Parse synchronously (so it will not skip directly to println("Outside query array: \(taskArray)")
), but I will not recommend you to do this.
现在,可以同步地下载解析的内容(因此它不会直接跳转到println(“外部查询数组:\(taskArray)”),但是我不会建议您这样做。
Instead I will recommend that you implement a closure which is called when the download is finished. Something similar to the following (PS, it's been written in Swift 2):
相反,我建议您实现一个闭包,在下载完成时调用该闭包。类似如下(PS,它是在Swift 2中写的):
//
// ViewController.swift
// ParseFun
//
// Created by Stefan Veis Pennerup on 21/09/15.
// Copyright (c) 2015 Kumuluzz. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
// MARK: - Lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
all { (tasks) -> Void in
print("The downloaded tasks are: \(tasks)")
}
}
// MARK: - Download methods
func all(completionHandler: ([String])->Void) {
// Creates the query
var taskArray = Array<String>()
let query = PFQuery(className:"Task")
let currentUser = PFUser.currentUser() // this will now be nil
query.whereKey("userId", equalTo: currentUser!)
// Starts the download
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) tasks.")
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
let title = object["title"]! as! String
taskArray.append(title)
print("Array: \(taskArray)")
}
}
completionHandler(taskArray)
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
}
}