-1

Actually I'm facing a similar situation in this link: CLGeocoder in Swift - unable to return string when using reverseGeocodeLocation

Sorry to duplicate it, but how to pass the string out of the completion block?


Thank you very much for your help, Sergey Birukov

Question Updated: To be more specifically, How can I store the "result" into the variable: "data"?

func asyncFunctionToBeCalled(arg1: AnyObject, arg2: AnyObject, aBlock: (result: String) -> Void) -> Void { 
//As you can see, this function receives aBlock variable which should point to the block you want to execute once this function is done
var res: String!
aBlock(result)
}

var data = ""

asyncFunctionToBeCalled("a", "b", { (result: String) in
//This block will be called when asyncFunctionToBeCalled is executed
//variable "result" is your requested string here
data = result
})
println(data)

console output nothing

Community
  • 1
  • 1
johnnyman
  • 129
  • 2
  • 11
  • What's your question? – Schemetrical Apr 13 '15 at 06:52
  • My question is how to return a string when using CLGeocoder().reverseGeocodeLocation. Just like the situation in the link I attached in the question. I still cannot figure how to do it after reading that post. Any help is appreciated Orz – johnnyman Apr 13 '15 at 06:58
  • That is not possible with async. You have to use your data inside the async block. – Arbitur Apr 13 '15 at 07:56
  • Not possible? really? So can I override the CLGeocoder.reverseGeocodeLocation method? – johnnyman Apr 13 '15 at 07:58
  • I think you have to read about async so you know how it works. http://www.webopedia.com/TERM/A/asynchronous.html – Arbitur Apr 13 '15 at 07:59

2 Answers2

3

Basically async is you asking someone else to ex. go shop groceries for you so you can continue with your programming and when he gets back from the store you receive the groceries and puts it in the refrigerator.

Practical example:

// Correct way of implementing
asyncShopGrocieries(["Milk", "Cookies", "Potatoes"]) { groceries in
    fridge.insert(groceries)
}

// Incorrect way of implementing
var groceries:[String]!              // You create a variable

asyncShopGrocieries(["Milk", "Cookies", "Potatoes"])     // You make an async request
{ groceries in                      // Block that handles the data when done
    groceries = groceries_
}                                   // Block will execute after you reach the end of this function

fridge.insert(groceries)           // When you come here you will try to put the groceries inside the fridge while he is still on his way TO the store.

UPDATE

class SomeClass {
    var groceries:[String]?
    var groceries2:[String]?
    var fridge = Fridge()



    func gotAllGroceries(groc: [String], groc2: [String]) {
        fridge.insert(self.groc, groc2)
    }
    
    func getGroceries() {
        asyncShopGrocieries(["Milk", "Cookies", "Potatoes"]) { groceries in
            self.groceries = groceries
            
            if groceries2 != nil {
                self.gotAllGroceries(self.groceries!, groc2: self.groceries2!)
            }
        }

        asyncShopGrocieries(["Candy", "Steak", "Apples"]) { groceries in
            self.groceries2 = groceries
            
            if groceries != nil {
                self.gotAllGroceries(self.groceries!, groc2: self.groceries2!)
            }
        }
    }
}

UPDATE 2

func async(time: UInt32, action: ()->()) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
        sleep(time)
        action()
    }
}


func testDispatchGroup() {
    let group = dispatch_group_create()
    
    let startDate = NSDate()
    
    dispatch_group_enter(group)
    async(2) {
        println("1 done")
        dispatch_group_leave(group)
    }
    
    dispatch_group_enter(group)
    async(1) {
        println("2 done")
        dispatch_group_leave(group)
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue()) {
        println("Everything done!")
        
        println("Total time: \(NSDate().timeIntervalSinceDate(startDate))")
    }
}

Prints out:

2 done
1 done
Everything done!
Total time: 2.00842797756195
Community
  • 1
  • 1
Arbitur
  • 38,684
  • 22
  • 91
  • 128
0

You are calling asynchronous function which receives block as an argument. You should call this function with your own block which receives a string as an argument. So when the asynchronous function is done it calls your block with resulted string. Example:

func asyncFunctionToBeCalled(arg1: AnyObject, arg2: AnyObject, aBlock: (result: String) -> Void) -> Void {
  //As you can see, this function receives aBlock variable which should point to the block you want to execute once this function is done
  var res: String!
  //Some asynchronous code here which will call aBlock(result)
}

//Your calling code:
asyncFunctionToBeCalled("a", "b", { (result: String) in
   //This block will be called when asyncFunctionToBeCalled is executed
   //variable "result" is your requested string here
})
  • thank you very much for your help, but I am still a little bit confused... is there any way I can define a variable and store the "result" of asyncFunctionToBeCalled? I tried to define a variable above "//Your calling code: ..." and println the variable and I got nothing – johnnyman Apr 13 '15 at 07:30