【问题标题】:what happens if delegate doesnot exist anymore?如果委托不再存在会怎样?
【发布时间】:2012-10-08 21:06:50
【问题描述】:

我在开发我的应用程序时遇到了一个有趣的问题。想象一下场景

  • 存在一个对象,我们称它为 A。
  • A,然后创建某个基于委托的类的对象 (B),例如 NSURLConnection。
  • A 将自己指定为 B 的委托,前提是 A 已实现所有必需的委托方法。
  • A 要求 B 开始其处理。在我们的示例中,即从某个服务器获取数据。
  • B 取完数据后,会立即调用 A 的某个指定方法。

在最后一步中,假设在调用 A 的方法时,B 发现 A 对象不再存在。然后会发生什么???

我不确定,但它会导致崩溃吗?

如果是,请建议我如何避免这种情况。

在我的例子中,我将视图控制器分配为某个对象的委托,例如 viewDidLoad 方法中的 X。在某些情况下,视图控制器在 X 调用视图控制器中定义的委托方法之前被销毁。

  • 如果将 X 的委托分配给 nil 可以解决问题。那么在哪 我应该这样做吗?

简而言之,哪个方法在视图控制器的卸载阶段同样只被调用一次 viewDidLoad 处于加载阶段。

【问题讨论】:

  • 请注意,NSURLConnection确实保留其代表。
  • @Guillaume 是的,你是对的。一切都是为了保留代表。如果我们将代理设置为 nil,那就更好了。
  • 是的,它肯定会导致崩溃。

标签: ios uiviewcontroller delegates crash viewdidload


【解决方案1】:

在类之间实现这种通信(A 类可以随时解除分配)的最佳方式是收听 NSNotifications
正如您所说,使用 weak(assign) 代表很危险,需要额外考虑。
使用 strong 委托也会造成内存膨胀(为什么我们要在视图控制器从视图中弹出它之后保留这么久?)。

有关 NSNotificationCenter 和通知的更多信息,您可以在 SDK 文档中找到大量信息。具体问题,您知道在哪里提问。

【讨论】:

    【解决方案2】:

    您不应该遇到这样一种情况:一个对象持有对另一个对象的引用,而该引用可能会在没有通知所有者对象的情况下被释放到其他地方。

    在释放对象 A 时通知对象 B(例如,通过在对象 B 中创建成员 a nill)或修改您的设计/流程以永远不允许在 B 之前释放 A完成(例如,如果可能,在B 中分配为代表时保留A

    【讨论】:

      【解决方案3】:

      检查一个有效的委托对象就足够了。

      if (delegate)
         [delegate method];
      

      【讨论】:

      • 具体来说 NSURLConnection 类,你的意思是它不会寻找视图控制器或视图控制器的“ - (void)connectionDidFinishLoading:(NSURLConnection *)connection” 方法,如果视图控制器不存在任何更多?
      • 如果委托被解除分配,那么“委托”将指向一些垃圾指针。我(和 MVC 设计模式)更喜欢对这种流使用通知。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 2010-10-07
      • 1970-01-01
      相关资源
      最近更新 更多