可以保留ASIHTTPRequest委托吗?

时间:2011-06-30 00:44:02

标签: objective-c delegates asihttprequest retain assign

是否可以保留ASIHTTPRequest的子类的代理?

我创建了ASIHTTPRequest的子类JSONRequestJSONRequest的每个实例都是自己的委托,处理回调,并将它们传递给jsonDelegate,这是JSONRequest的私有属性,并响应requestFinished:withResult:,其中result是JSON响应的NSDictionary表示。为此,我在setDelegate:中将JSONRequest重载为super.delegate = self; self.jsonDelegate = newDelegate

在这种情况下保留jsonDelegate是否可以,因为jsonDelegate通常是一个视图控制器,如果用户点击“返回”,有时会在加载请求时解除分配。我将发布在调用回调方法后jsonDelegate中的JSONRequest

我如何知道这是好的,不会导致retain loop

3 个答案:

答案 0 :(得分:5)

什么保留了请求? (操作队列,也许?谁知道?)

一般来说,你似乎提出的“火与忘,给我回调”方法是一个坏主意。如果除了请求之外没有任何东西保留VC,那么(除非你的应用程序结构有点愚蠢)VC将永远不会对它收到的数据做任何事情,所以没有理由继续它。

它也感觉不对:请求是否拥有VC,或者VC是否拥有该请求?我期待后者,所以VC也应该保留请求。

有几个例外:

  • CAAnimation.delegate被保留,大概是因为动画将在某个时刻完成(我不确定如果它是重复动画会发生什么)。 UIKit的动画代表也是如此。
  • NSTimer保留其目标,可能是因为NSInvocation确实如此。 (我写了一个“弱计时器”课来解决这个问题。)
  • CADisplayLink保留其目标,可能与NSTimer相似。

对于这些情况,我经常使用“弱代理”类来解决它,它不保留其目标(我在NSTimer / CADisplayLink周围编写了一个“弱定时器”包装器,以使这更容易。)

所要做的要做的是跟踪你发起的请求和dealloc,做类似的事情

request.delegate = nil;
[request cancel];
self.request = nil;

同样,您应该在适当的时间取消注册通知/操作/ KVO回调。有一个例外:

  • 如果您确定在发布后不会向您发送回叫,则无需费心,因此不需要清除文本字段代理和按钮操作/目标。

例外有例外:

  • UIWebView(至少在较旧的操作系统中)也被其他东西保留,可能与网络线程有关。如果在Web视图仍在加载时VC消失,它可能会崩溃。
  • UIScrollView滚动回调还会导致视图在VC的生命周期内保留。您可以通过以下方式测试:发布“完成”时,按住“完成”并开始轻弹。

答案 1 :(得分:2)

如果您的发布是确定性的(如果您承诺它将永远发生,即使出现错误,超时或其他类型的意外事件 - 如连接只是无限期挂起) - 那么这很好(没有保留循环)。

在这种情况下,保留循环总会在某个时刻被破坏。

答案 2 :(得分:1)

我知道这个问题最初是关于ASIHTTPRequest的,但是人们可能偶然发现这个线程并且可能会让他们认为使用ASIHTTPRequest仍然是最佳实践 - 事实并非如此,事实上发展已经在2011年AFAIK停止了。

使用更默认使用块的现代HTTP库(我更喜欢AFNetworking),在发布块之前,会复制或保留在失败/成功块中引用的所有变量。这将使您无需担心整个内存管理问题 - 除非您在其中一个块中使用self,否则您将创建一个保留周期,直到块被释放。