iPhone - 更改委托可能导致异步调用崩溃?

时间:2011-08-05 13:17:05

标签: iphone ios memory-management asynchronous delegates

我有一个实例化另一个类的类,并作为第二个类的委托。第二类是“免费”的,并不是第一类保留的。

第二个类发送异步HTTP请求并听取他们的响应 收到响应后,将对其进行解析,并重新打包结果并将其发送给其中一个委托方法。调用委托后,第二个类实例将自行释放。节目结束。

为了确保获得服务器答案,当第一个类进入dealloc(由于任何原因)时,它会更改第二个类的委托属性以将答案路由到applicationdelegate。

但是......在更改该委托属性时,我认为异步的http答案可能会与第一个类的dealloc进程发生冲突。所以第一堂课在解除分配时会收到答案。在这种情况下,第一个类将收到它无法管理的答案(可能会崩溃),第二个类将永远不会看到委托在调用发送到第一个类之后发生了变化。

你如何具体地解决这个问题?

以下是该流程的架构:

  • AppDelegate创建A1,A2,A3。
  • 每个Ax创建一个B实例对象(发送HTTP请求的B1,B2,B3),每个Ax被定义为Bx的委托
  • 此时,所有A和B类实例都可能有生命
  • 如果Ax实例死掉,Bx类可能会将答案发送到appdelegate而不是Ax实例

2 个答案:

答案 0 :(得分:2)

如果 A B 的代表,则会出现问题,但 A 不允许保留 B

  1. B 必须知道委托 A 仍然存在,或者在需要时设置为nil
  2. 必须知道 B 仍然存在,否则它无法安全地将自己删除为委托。
  3. 因此,要么取消保留限制,请让 A 正确保留 B

    或者使用通知来寻找一个耦合度较低的解决方案。

    1. B 定义通知,并在其上发布。
    2. A 在创建时注册为通知的侦听器,并在取消分配时注销。

答案 1 :(得分:0)

  

为了确保获得服务器答案,当第一个类进入dealloc(由于任何原因)时,它会更改第二个类的委托属性以将答案路由到应用程序委托。

这对我来说听起来不是一个明智的建筑。不应该以你的方式来扮演代表。将与服务器通信的代码分解为自己的类,只要您需要它就会持续存在。不要将您的网络代码在整个应用程序中传播到始终进出的对象中,并且在您需要多个地方可用的内容时,不要将您的应用程序代理视为一个捕获。