iOS对象或两个控制器之间的委托?

时间:2016-08-24 13:18:59

标签: ios swift delegates segue weak-references

晚上,我的问题充满了理论。

我理解从 Apple开发人员文档中读取,最好使用委托模式来跟踪某些对象属性。通过这种方式,我们可以访问代理而无需访问该对象。 (我真的没有得到这个选择的原因)

我也明白最好定义:protocolDelegate: class 当我们在类中声明委托时,最好使用weak字来防止某种“问题循环”。 (??)

所以,当我玩代码时,我发现你不能在两个weak delegate之间传递view controllers,因为当然,当你更改控制器时,{ {1}}将被删除,因为它是一个weak delegate的东西(或者至少这是我所理解的)。

所以,我必须在2个选项中进行选择:

  • 使代理人“强势”删除weak密钥。

  • 或传递segue中的对象并将代理保持为weak

我有很多困惑,你能清醒一下吗? :d

4 个答案:

答案 0 :(得分:2)

您所指的周期称为保留周期

让我们用一个具体的例子来澄清这一点:假设你有一个UIViewController,其UITableView。视图控制器具有对表视图的强引用。视图控制器现在想要充当表视图的委托。

现在,如果表视图具有对其委托的引用,我们将遇到以下情况:视图控制器具有对表视图的强引用,并且表视图依次将有一个强大的参考回到视图控制器。因此,两者都不能被解除分配。

要打破此周期,对代理的引用通常是。这允许视图控制器的保留计数最终降至0,这又可以释放表视图。

您希望使用委托的类也应遵循此模式,并使用 weak 对其委托的引用。因此,您应该通过segue传递所需的参考资料。

答案 1 :(得分:2)

我会集中讨论你问题的第一部分,因为之前的答案很好地涵盖了其余部分。

考虑以下情况:您有一个处理某种网络连接的类 - 它向服务器发送请求并获得响应。在这个类之外有一个viewController,它有一个触发请求的按钮和一个向用户显示响应的视图。

基本上,网络处理类应该能够一方面从viewController(按下按钮)获取一些消息,另一方面传递viewController响应。所以两个类之间应该有双向通信。虽然将buttonPressed消息传递给网络处理类非常明显,但反向部分(传递响应)有点棘手,因为网络处理类不应该知道谁创建了它并且谁调用它(好的OO)实践和内存泄漏预防)。

这是代理模式进入的点。它允许对象将数据传递给任何对其感兴趣的人,而不知道有关接收者的任何信息。通过响应的类只知道一些代理'而不是另一个班级。此外,您可以按原样取出网络处理类并将其放入另一个项目中。因为它不应该知道其原始项目中的任何其他类,只有一些“委托”,它可以放入另一个项目而不做任何修改。

我希望它可以帮助您了解选择的原因。

答案 2 :(得分:1)

我认为使用segue传递对象,Segues是在Xcode中使用Storyboard的一个非常重要的部分。我们可以再次讨论不同类型的segues,但是这个会向您展示如何使用“显示”segue,以及如何pass data between两个视图控制器来自定义第二个无论需要什么样的自定义数据。

您可以轻松使用segues示例;在下面,您可以currentstringdestinationViewControllersentstring发送,ShowSegue是您的segue identifier

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "ShowSegue" {
        if let destinationVC = segue.destinationViewController as? OtherViewController {
            destinationVC.sentstring = currentstring
        }
    }

}

答案 3 :(得分:1)

viewcontrollers之间的导航维护stack个viewcontrollers。

例如aVC是firstviewcontroller,然后堆栈顶部将是aVC

现在当你推或显示另一个viewcontroller说bVC时,现在statck的顶部是bVC。所以堆栈看起来像,

aVC -> bVC(top)

现在你再推另一个cVC

aVC -> bVC -> cVC(top)

因此,用户始终可以看到堆栈顶部。

在目前情况下,aVC和bVC以及cVC不会解除分配。他们在记忆中。但是如果你弹出或者解雇cVC,那么它将从内存中解除分配,现在你的堆栈顶部看起来像,

aVC -> bVC(top)

因此,viewcontrollers生活在堆栈中,直到它们没有被弹出或移除。因此,默认情况下它们是strog参考。

Segue只不过是你可以说它们是推送或弹出操作的图形表示。

另一件事是委托应该是weak,因为如果它们很强大,它可以创建保留周期。

一般来说,您可以将委托称为representative

现在,如果您正在使用segue,请在prepareForsegue中发送您的对象,它将管理其他所有内容。