如何在闭包内调用函数 [英] How To Call a func within a Closure

查看:209
本文介绍了如何在闭包内调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在模型的类Location中,我得到了当前城市的名称:

In a model's class Location, I get the name of the current city:

var currentLatitude: Double!
var currentLongitude: Double!
var currentLocation: String!
var currentCity: String!

func getLocationName() {

    let geoCoder = CLGeocoder()
    let location = CLLocation(latitude: currentLatitude, longitude: currentLongitude)

    geoCoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in
        guard let addressDict = placemarks?[0].addressDictionary else {
            return
        }
        if let city = addressDict["City"] as? String {
            self.currentCity = city
            print(city)
        }
        if let zip = addressDict["ZIP"] as? String {
            print(zip)
        }
        if let country = addressDict["Country"] as? String {
            print(country)
        }

        self.nowUpdateUI()
    })
}

在视图控制器中,我想更新UI并更新标签以显示当前城市. 但是,self.currentCity = city发生在闭包内部.因此,如果我只是在视图控制器中运行func:

In view controller I want to update the UI and update my label to show the current city. However, self.currentCity = city happens inside of a closure. So if I just run a func in view controller:

func updateUI() {
        cityLbl.text = Location.sharedInstance.currentCity
}

  • 我什么也没得到,因为关闭尚未完成运行. 建议我在getLocationName()中添加一个完成处理程序,并在其中执行对FUNC的调用,以更新UI. 但是,从所有有关闭包,完成处理程序的教程中,我还不清楚如何实现这一点. 如何构造完成处理程序,将其作为arg传递给getLocationName(),以及如何从视图控制器调用getLocationName?
    • I'm not getting anywhere because the closure haven't finished running. I've been advised to add a completion handler to getLocationName() and inside of it, perform the call to a func that will update the UI. However, from all the tutorials out there on closures, completion handlers, it is not clear to me how to achieve that. How to construct a completion handler, pass it as an arg to getLocationName() and how to call getLocationName from view controller?
    • 推荐答案

      要处理这种情况,您可以有多种选择.

      To handle this situation you have multiple option.

      1. 使用您的位置信息类创建delegate/protocol

      1. Create delegate/protocol with your Location class

      • 创建一个协议,并使用ViewController实现该协议方法,并在Location类中声明其实例.之后,在reverseGeocodeLocationcompletionHandler中调用此委托方法.在 Protocol 上查看Apple文档.更多细节.
      • Create one protocol and implement that protocol method with your ViewController and declare its instance in your Location class. After then in the completionHandler of reverseGeocodeLocation call this delegate method. Check Apple documentation on Protocol for more details.

      您可以使用Location类的getLocationName方法创建completionHandler.

      You can create completionHandler with your getLocationName method of Location class.

      • getLocationName添加completionHandler并在reverseGeocodeLocationcompletionHandler内这样调用completionHandler.

      • Add completionHandler with getLocationName and called that completionHandler inside the completionHandler of reverseGeocodeLocation like this way.

      func getLocationName(completionHandler: @escaping (_ success: Bool) -> Void) {
      
          let geoCoder = CLGeocoder()
          let location = CLLocation(latitude: currentLatitude, longitude: currentLongitude)
      
          geoCoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in
              guard let addressDict = placemarks?[0].addressDictionary else {
                  completionHandler(false)
                  return
              }
              if let city = addressDict["City"] as? String {
                  self.currentCity = city
                  print(city)
              }
              if let zip = addressDict["ZIP"] as? String {
                  print(zip)
              }
              if let country = addressDict["Country"] as? String {
                  print(country)
              }
              completionHandler(true)
              //self.nowUpdateUI()
          })
      }
      

      现在在调用此函数的ViewController中,在完成块内调用updateUI方法.

      Now in ViewController where you are calling this function call your updateUI method inside the completion block.

      Location.sharedInstance.getLocationName { (success) in
          if success {//If successfully got response
              self.updateUI()
          }
      }
      

      您可以为(NS)NotificationCenter添加观察者.

      You can add observer for (NS)NotificationCenter.

      • (NS)NotificationCenter注册观察者,然后在reverseGeocodeLocationcompletionHandler中发布通知.您可以通过以下 StackOverflow帖子来获得更多详细信息.
      • Register the observer with (NS)NotificationCenter and then post the notification inside the completionHandler of reverseGeocodeLocation. You can get more detail on this with this StackOverflow Post.

      这篇关于如何在闭包内调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆