Swift信号量在调用UI之前没有等待函数完成

时间:2016-05-25 02:20:54

标签: ios swift mapkit semaphore

我正试图推迟一段时间,直到我收到来自reverseGeocodeLocation电话的回复。但是,当使用断点检查值实际更改时,它仍然在UI转换发生后发生。我已经尝试将函数设置为空,并且当前String返回。

编辑代码:

func getReversedGeocodeLocation(completionHandler: (String, NSError?) ->()) {

    let semaphore = dispatch_semaphore_create(0)

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in

        CLGeocoder().reverseGeocodeLocation(self.newMeetupLocation, completionHandler: {(placemarks, error) -> Void in

            if error != nil {
                print("Reverse geocoder failed with error" + error!.localizedDescription)
                return
            }
            else if placemarks?.count > 0 {

            }
            else {
                print("Problem with the data received from geocoder")
            }

            completionHandler(placemarks!.first!.name! ?? "", error)
        })

        dispatch_semaphore_signal(semaphore)

    }
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}

旧代码:

let semaphore = dispatch_semaphore_create(1) //even with 0, it's not working

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in

            self.newAddress = self.getReversedGeocodeLocation()

            dispatch_semaphore_signal(semaphore)
        }

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)

        //dispatch_semaphore_signal(semaphore)

        print(self.newAddress + ".")

        self.performSegueWithIdentifier("mainToNewAddress", sender: self)

func getReversedGeocodeLocation() -> String{

    var address = ""
    CLGeocoder().reverseGeocodeLocation(self.newAddressLocation, completionHandler: {(placemarks, error) -> Void in

        if error != nil {
            print("Reverse geocoder failed with error" + error!.localizedDescription)
            return
        }
        else if placemarks?.count > 0 {
            let pm = placemarks?.first!
            address = pm!.name!
        }
        else {
            print("Problem with the data received from geocoder")
        }
    })

    return address
}

2 个答案:

答案 0 :(得分:2)

使用信号量并将调用分派给getReversedGeocodeLocation不必要地复杂化。 CLGeocoder().reverseGeocodeLocation已经异步。如果您只是将完成处理程序闭包传递给getReversedGeocodeLocation,那么您可以使用它来调用segue;

self.getReversedGeocodeLocation(self.newAddressLocation, completionHandler: { (address,error) in 
    guard error == nil else {
        print("Reverse geocoder failed with error" + error!.localizedDescription)
        return
    }

    guard let address = address else {
        print("No address returned")
        return
    }

    self.newAddress = address
    dispatch_async(dispatch_get_main_queue(), {
        self.performSegueWithIdentifier("mainToNewAddress", sender: self)
    })
})

func getReversedGeocodeLocation(addressLocation: String, completionHandler:((address: String?, error: NSError?) -> Void))) {
    CLGeocoder().reverseGeocodeLocation(self.newAddressLocation, completionHandler: {(placemarks, error) -> Void in

        var address = nil

        if placeMarks.count > 0 {
            if let pm = placeMarks!.first {
                address  = pm.name
            }
        } else {
            print("Problem with the data received from geocoder")
        }

        completionHandler(address,error)
    })
}

答案 1 :(得分:0)

我不认为它是信号量的问题,它与你的getReversedGeocodeLocation函数有关。 CLGeocoder().reverseGeocodeLocation是一个异步函数,因此return语句将在CLGeocoder().reverseGeocodeLocation的完成块执行之前执行,这就是为self.newAddress分配一个空字符串的原因。

要修复此问题,您可以使用getReversedGeocodeLocation中的另一个信号量来阻止,直到完成处理程序完成,或者使用委托来通知完成处理程序已完成(这通常是正确的方法) )。