从父ViewController迅速3调用函数 [英] swift 3 call function from parent ViewController

查看:35
本文介绍了从父ViewController迅速3调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ViewController,该视图容器有一个创建2个容器视图的类,并向第一个容器添加了一个表,为第二个容器添加了一个HashtagPicker.

I have a ViewController, this view container has a class which creates 2 container views, and adds a table to the first container and a HashtagPicker for the second.

hashTagPicker具有一个函数,只要对选定的hashTag进行更改,就会调用该函数.

The hashTagPicker has a function which is called whenever a change to the selected hashTags happens.

问题:无论何时更改标签,我都想调用更新表功能.如何从包含容器的类中定义的hashtagclass调用函数?

question: i want to call a update table function whenever a tag is changed. How can i call a function from the hashtagclass which is defined in the class that contains the containers?

推荐答案

我个人喜欢通知的委托方法-后一种解决方案几乎总是导致体系结构混乱.可悲的是,委托方法的示例(也是公认的答案)甚至更糟-它基本上为内存泄漏提供了机会.我会解释.在公认的解决方案中, ParentView 持有对 HashtagPicker 的强烈引用,而 HastagPicker 持有对 ParentView的强烈引用,这将创建一个保留周期,这意味着两个控制器都不会被ARC接收并被取消初始化.因此,例如,如果您要从其他视图中呈现 ParentView ,并且继续进入 ParentView 并返回,则将继续生成 ParentView (和 HashtagPicker ),而旧的仍然占用内存.

I personally like the delegate approach over notifications - the latter solution almost always leads to confusing architecture. Sadly, the example for the delegate approach, which is also the accepted answer, is even worse - it basically opens an opportunity for memory leaks. I'll explain. In the accepted solution, ParentView is holding a strong reference to HashtagPicker and, in turn, HastagPicker is holding a strong reference to ParentView, this creates a retain cycle and means neither of the controllers will be picked up by ARC and be deinitialized. So, if you are, for example, presenting ParentView from some other view and you keep going to ParentView and back, you will keep spawning new instances of ParentView (and HashtagPicker) with old ones still occupying memory.

现在,应该怎么做.我将使用与接受的答案完全相同的名称.

Now, how this should have been done. I'll use exactly the same names as in the accepted answer.

协议的定义应如下:

// note the ": class" part
protocol HashTagPickerDelegate: class {
  func picked(hashtag: String)
}

如果我们指定 class ,则意味着该协议只能在类上使用.这将允许使用它来创建弱引用,否则将是不可能的.

If we specify class, it means the protocol can only be used on classes. This will allow use to create weak reference, which otherwise would have been impossible.

class HashtagPicker: UIViewController {
  // if HashTagPickerDelegate wouldn't be limited to class, 
  // we couldn't have made a weak reference here!
  weak var delegate: HashTagPickerDelegate?

  // at some point, you call the delegate, it can be anywhere, this is just an example
  @IBAction func tappedHashtag(_ sender: Any) {
    delegate?.picked(hashtag: "bla")
  }
}

现在我们对委托的引用很少,因此没有保留周期,ARC可以很好地清理所有内容!

Now we have a weak reference to delegate, so there is not retain cycle and ARC can clean up everything nicely!

我将剩下的代码作为完整的答案:

I'll throw in the rest of the code to have this as a complete answer:

class ParentView: UIViewController {
  func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // we are presenting the nested controller
    if segue.identifier == "SegueHastagPickerContainer",
       let destinationController = segue.destination as? HashtagPicker {
      destinationController.delegate = self
    } 
  }
}

extension ParentView: HashTagPickerDelegate {
  func picked(hashtag: String) {
    // we just got info from the child controller, do something with it!
  }
}

这篇关于从父ViewController迅速3调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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