1

I have such query to parse.com. Why the numObjects variable has different values ​​inside the findObjectsInBackgroundWithBlock and on the function exits

func searchUserInParse () -> Int {

    var numObjects : Int = 0 // the num return objects from query

    var query = PFQuery(className:"Bets")
    query.whereKey("user", equalTo: "Bob")
    query.findObjectsInBackgroundWithBlock {
        (objects: AnyObject[]!, error: NSError!) -> Void in
        if !error {
            numObjects = objects.count
            println(numObjects) // at this point the value = 1
        } else {
            // Log details of the failure
            NSLog("Error: %@ %@", error, error.userInfo)
        }
    }
    println(numObjects) // at this point the value = 0

    return numObjects
}
1
  • This is because the block runs on a background thread asynchronously (take a look at the method name). Because it's asynchronous, it returns immediately and moves on to the code after it. This means that the second println(numObjects) is called before the above code block. Commented Jun 29, 2014 at 9:50

3 Answers 3

4

Instead of using findObjectsInBackgroundWithBlock which runs asynchronously, try using findObjects which runs synchronously:

//Set up query...
var objects = query.findObjects()
numObjects = objects.count
println(numObjects)

Then when running your function, do it like so:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) {
    //Search users
    searchUserInParse()

    dispatch_async(dispatch_get_main_queue()) {
        //Show number of objects etc.
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it works. But I get Warning: A long-running Parse operation is being executed on the main thread. Break on warnParseOperationOnMainThread() to debug.
2

That's the nature of async code, your function will run the outer code to completion, then some time later (depending on connection speed and query complexity) the completion block will run.

Your calling code should do something like the following:

  • create the query
  • start the query with a completion block
  • show a loading animation
  • return (query results still unknown)

Then you should think about the inside of the block:

  • check for errors
  • update values that the UI is bound to
  • tell the UI to refresh

You can't have a function that will return the count, but you could write a function that takes a completion block as a parameter, and executes it in the query completion block. That's a bit more advanced though.

Comments

1

query.findObjectsInBackgroundWithBlock is will be executed asynchronously , the completion block is called after fetching objects. therefore the code after the block called first hence numObjects value is 0.

1 Comment

then what is the solution to it. I mean what if we need to do the processing asynchrously.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.