使用闭包中的委托传递数据

Posted

技术标签:

【中文标题】使用闭包中的委托传递数据【英文标题】:Passing data with a delegate from a closure 【发布时间】:2018-02-03 22:12:02 【问题描述】:

我有两个视图控制器,我正在尝试将数据从一个传递到另一个。数据从 MKLocalSearch 闭包返回。但我似乎无法让我的委托方法运行。我希望有人能对此有所了解吗?我模拟了我正在尝试做的一个较小的版本。另外,我不使用故事板。我把所有东西都编码了。这是代码...

import UIKit
import MapKit

protocol SendDataDelegate 
    func sendData(data: String)


class OneViewController: UIViewController 

var delegate: SendDataDelegate?

override func viewDidLoad() 
    super.viewDidLoad()

    doSearch()  coord in
        if let coord = coord 
            //When the execution gets here, coord does have
            //the values to be sent to the nexr view controller.
            self.delegate?.sendData(data: "\(coord)")
            let twoViewController = TwoViewController()
            self.present(twoViewController, animated: true)
        
    


func doSearch(completion: @escaping (CLLocationCoordinate2D?) -> Void) 

    var coord: CLLocationCoordinate2D?
    let request = MKLocalSearchRequest()

    request.naturalLanguageQuery = "New York"

    let search = MKLocalSearch(request: request)

    search.start(completionHandler: (response, error) in

        if error != nil 
            print("Error occured in search:\(error!.localizedDescription)")
         else if response!.mapItems.count == 0 
            print("No matches found")
         else 
            print("Matches found")

            coord = response?.mapItems[0].placemark.coordinate
        
        completion(coord)
    )
  


import UIKit

class TwoViewController: UIViewController, SendDataDelegate 

var myData: String = ""
var oneViewController = OneViewController()

override func viewDidLoad() 
    super.viewDidLoad()
    oneViewController.delegate = self


func sendData(data: String) 
    myData = data
    print ("myData: \(myData)")



【问题讨论】:

【参考方案1】:

在您的TwoViewController 中,您有一个属性,其中包含OneViewController另一个 实例,并将它的委托设置为self

因此,每次创建TwoViewController 的实例时,都会创建一个OneViewController 的新实例,但由于显示OneViewController 的实际视图,它们实际上都不是那个实例。

在你的情况下,委托模式不合适,你最好直接调用TwoViewController的方法:

class OneViewController: UIViewController 

    //no need to have a delegate

    override func viewDidLoad() 
        super.viewDidLoad()

        doSearch()  coord in
            if let coord = coord 
                //When the execution gets here, coord does have
                //the values to be sent to the nexr view controller.
                let twoViewController = TwoViewController()
                twoViewController.sendData(data: "\(coord)")
                self.present(twoViewController, animated: true)
            
        
    

    //...    


class TwoViewController: UIViewController 

    var myData: String = ""
    //Creating a new instance of `OneViewController` has no meaning.

    override func viewDidLoad() 
        super.viewDidLoad()
        //Useless to set the delegate of newly created `OneViewController`.
    

    func sendData(data: String) 
        myData = data
        print ("myData: \(myData)")
    


如果您有任何理由在TwoViewController 中拥有属性oneViewController,请解释原因。您当前的代码没有任何解释。

【讨论】:

您对参考的看法是绝对正确的。我休息了一下。回来看到错误的参考。我现在的委托模式可以正常工作了!谢谢。

以上是关于使用闭包中的委托传递数据的主要内容,如果未能解决你的问题,请参考以下文章

将数据从委托 Swift 类传递到 SwiftUI 结构中的 EnvironmentObject

python高级-闭包-装饰器

从委托的源 ViewController 调用异步闭包

如何从从 Firebase 检索信息的闭包中传递数据?

使用委托将数据从模态视图传递到父视图(在情节提要中使用 segue)

在 ViewControllerB 到 ViewControllerA 之间传递数据,委托不会被调用