使用协议发送数据

Sending data using protocols

我在使用协议将数据发送回之前的控制器时遇到问题。我研究了 SO 问题和指南,但出于某种原因,我的数据没有传回。

在我的第二个 class 中,我创建了数据,该数据稍后被发送回第一个 class:

protocol ImageEditorDelegate {
    func sendImage(image: UIImage, id: String)
}

class PhotoEditorViewController: UIViewController { 

    var delegate: ImageEditorDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
  }

@IBAction func didPressSave(_ sender: UIButton) {
        delegate?.sendImage(image: finalImage, id: imageThatWasSelected)
        self.dismiss(animated: true, completion: nil)
    }

}

在我的接收中 class 我有:

class NewProductViewController: UIViewController, ImageEditorDelegate { 

    var imageEditor: PhotoEditorViewController?

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

func sendImage(image: UIImage, id: String) {
        print("Receiving images", image, id)
        switch id {
        case "1":
            selectedImages[1] = image
            productImage1.image = image
        case "2":
            selectedImages[2] = image
            productImage2.image = image
        case "3":
            selectedImages[3] = image
            productImage3.image = image
        default:
            break
        }
    }
}

但是没有任何反应,这个函数永远不会被调用。我认为我的代表为零,或者如此,但我该如何解决这个问题?我还有,我正在使用 VIPER 作为具有稍微定制的 segues 的架构,这可能是问题所在吗?我尝试过简单的 segues,但遇到了同样的问题。

我知道这是一个相当简单的问题,但是在阅读了有关协议的文章后,我无法理解我做错了什么。

感谢您的帮助!

您需要实例化您的 photoEditor,例如

photoEditor =  PhotoEditorViewController() 

在尝试设置其委托之前。

下一部分您不必执行此操作,但我建议将委托变量设为弱变量以避免任何保留问题,就像这样

weak var delegate: ImageEditorDelegate?

并且您需要像这样将协议标记为 class

protocol ImageEditorDelegate : class {

你的做法是非常错误的。你有两个视图控制器 属性 相互引用:

class PhotoEditorViewController: UIViewController { 
    var delegate: ImageEditorDelegate?
}
class NewProductViewController: UIViewController, ImageEditorDelegate { 
    var imageEditor: PhotoEditorViewController?
}

这些不是 weak 引用,所以如果你真的让它工作——也就是说,如果你曾经安排过 NewProductViewController 的 imageEditor 是一个 PhotoEditorViewController,它的 delegate 是 NewProductViewController — 你将遇到讨厌的保留周期和内存泄漏。

这表明您还没有理解协议和委托模式。只有呈现的视图控制器应该有一个 delegate 属性 指向呈现器,它应该是 weak。演示者不需要任何 属性 指向被呈现的视图控制器,因为它会呈现它。