0

保留一个子类的代表可以ASIHTTPRequest吗?

我做了一个ASIHTTPRequest被调用的子类JSONRequest。的每个实例JSONRequest都是它自己的委托,处理回调,并将它们传递给jsonDelegate,这是 的私有属性JSONRequest,并响应requestFinished:withResult:,其中结果是NSDictionaryJSON 响应的表示。为此,我重载setDelegate:JSONRequestto do super.delegate = self; self.jsonDelegate = newDelegate

在这种情况下是否可以保留jsonDelegate,因为通常jsonDelegate是一个视图控制器,如果用户点击“返回”等,它有时会在请求加载时被释放。我将jsonDelegateJSONRequest调用回调方法后释放。

我怎么知道这没问题并且不会导致保留循环

4

3 回答 3

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(至少在较旧的操作系统中)也被其他东西保留,可能与网络线程有关。如果 VC 在 Web 视图仍在加载时消失,它可能会崩溃。
  • UIScrollView 滚动回调也会导致视图在 VC 的生命周期之后被保留。您可以通过例如按住“完成”并在释放“完成”时开始轻弹来测试这一点。
于 2011-06-30T01:53:52.030 回答
2

如果您的发布是确定性的(如果您保证它总是会发生,即使在出现错误、超时或其他某种意外事件的情况下——比如连接只是无限期地挂起)——那么这很好(没有保留循环) .

在这种情况下,保留循环总是会在某个时候中断。

于 2011-06-30T01:35:03.483 回答
1

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

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

于 2012-05-04T15:29:40.540 回答