委派给另一个视图控制器不起作用

时间:2018-09-08 18:33:36

标签: ios swift swift-protocols delegation

我的委托发送者类:

import UIKit

protocol tapDelgation:class {
    func tapConfirmed(message:String)
}

class ViewController: UIViewController {
    weak var delegate:tapDelgation?

    @IBAction func deligateSenderAction(_ sender: Any) {
        var data = "hello world"
        print(data)
        self.delegate?.tapConfirmed(message: data)
    }
}

我的接收者班级:

import UIKit

class NextViewController: UIViewController {
    weak var vc:ViewController? =  ViewController()

    override func viewDidLoad() {
        super.viewDidLoad()
        vc?.delegate = self
    }
}

extension  NextViewController : tapDelgation {
    func tapConfirmed(message: String) {
        print(message)
    }
}

预期结果:按下发送方vc上的一个按钮,将从接收方vc中弹出控制台打印。但徒劳无功。有谁知道为什么会这样吗?如果不可能,那为什么呢?

3 个答案:

答案 0 :(得分:2)

在我看来,这是内存管理问题。

第一个问题:创建带有默认初始化器(例如ViewController())的视图控制器几乎从来都不是正确的选择。因为它没有任何视图内容。

您无需解释如何创建和显示NextViewControllerViewController

似乎NextViewControllerViewController的引用很弱,并且ViewController的委托点也很弱(代理引用几乎总是很弱。)

此行:

weak var vc:ViewController? =  ViewController()

将导致NextViewController创建一个ViewController的实例,该实例不归任何人所有,因此将立即释放该实例,并且vc变量将返回nil。到您进入NextViewController的viewDidLoad时,vc将为nil,因此行vc?.delegate = self中的可选绑定将不会执行任何操作。

NextViewController的{​​{1}}变量几乎应该是强引用,而不是弱引用,但是您没有显示vc曾经如何显示在屏幕上,因此它不是。弄清楚你要做什么。

答案 1 :(得分:1)

weak var vc:ViewController? =  ViewController()

如果您没有在其他地方设置vc,并且其他任何实例都没有对其进行强引用,请删除弱项。

如果还有一个实例具有很强的参考意义,请分享相关代码。

https://stackoverflow.com/users/205185/duncan-c的答案是完全正确的,除非有任何其他代码会影响NextViewController的显示方式和对vc: ViewController的引用

  

我将viewController更改为SenderViewController,但是没有运气,并且发件人和接收者通过导航控制器连接。即,如果我按发件人上的按钮,则通过推送过渡会收到一条收据。我的目标是由于触发了IBAction,因此第二个视图控制器将实现点击确认功能。感谢您的回答。学到很多:)

由于此注释,您需要在ViewController(原始版本)中实现prepareForSegue()方法,并在那里设置“ next”视图控制器的vc属性,而不是在“ next”中设置= ViewController()在ViewController上进行扩展:

extension ViewController {
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let nextController = segue.destinationViewController as! NextViewController
        nextController.vc = self
    }
}

基于注释的说明:

您将获得一个新的NextViewController实例,并在其初始化时实例化ViewController的新实例(而不是将ViewController的原始实例传递给它)。在这里,您可以通过委派产生奇怪的行为。

答案 2 :(得分:1)

弱var vc:ViewController? = ViewController() 删除vc的弱点,消失后将释放视图控制器的内存