【问题标题】:Delegation to another view controller is not working委托给另一个视图控制器不起作用
【发布时间】:2019-02-13 17:39:30
【问题描述】:

我的委托发送者类:

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 弹出控制台打印。但徒劳无功,什么都没有发生。有谁知道为什么会这样?如果不可能,那为什么?

【问题讨论】:

  • NextViewController 在哪里显示vc
  • NextViewController 来自 ViewController 的页面转换之后
  • 您需要显示执行此操作的代码。
  • 我需要使用prepare吗??
  • 这真的取决于你如何准确地显示“ViewController”。我有一种感觉,您设置委托的“ViewController”实例实际上并不是正在显示的 ViewController 实例。

标签: ios swift swift-protocols delegation


【解决方案1】:

对我来说,这似乎是一个内存管理问题。

第一个问题:使用像ViewController() 这样的默认初始化程序创建视图控制器几乎从来都不是正确的做法。因为它不会有任何视图内容。

您没有解释您的NextViewController 和您的ViewController 是如何创建和显示的。

看起来NextViewControllerViewController 有一个弱引用,而ViewController 的委托点也很弱(委托引用几乎总是应该是弱的。)

这一行:

weak var vc:ViewController? =  ViewController()

将导致NextViewController 创建一个不属于任何人的ViewController 实例,因此它将立即被释放,vc 变量将返回为零。当您到达NextViewController 的viewDidLoad 时,vc 将为零,因此vc?.delegate = self 行中的可选绑定将不起作用。

NextViewControllervc 变量几乎可以肯定是一个强引用,而不是弱引用,但是你没有显示ViewController 是如何显示在屏幕上的,所以不清楚你是什么努力去做。

【讨论】:

  • 我将 viewController 更改为 SenderViewController 但没有运气,发送者和接收者通过导航控制器连接。即,如果我按下发件人上的按钮,则通过推送转换收到。我的目标是因为它触发了 IBAction,然后第二个视图控制器将实现点击确认功能。感谢您的回答。学到了很多:)
  • 你刚才所说的与我描述的内存管理问题没有任何关系。这一行:weak var vc:ViewController? = ViewController() 永远不会做任何有用的事情。它将创建一个视图控制器(或任何类型的对象),该控制器将立即被释放和丢弃。
【解决方案2】:
weak var vc:ViewController? =  ViewController()

如果你没有在其他地方设置 vc 并且任何其他实例都没有保持对它的强引用,请删除weak。

如果有其他实例强引用,请分享相关代码。

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

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

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

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

根据评论解释:

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

【讨论】:

    【解决方案3】:

    弱变量 vc:ViewController? = 视图控制器() 去掉weak for vc会在消失后释放视图控制器内存

    【讨论】:

      猜你喜欢
      • 2018-01-01
      • 2017-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多