【问题标题】:ASIHTTPRequest popViewControllerAnimated: => delegate EXEC_BAD_ACCESSASIHTTPRequest popViewControllerAnimated: => 委托 EXEC_BAD_ACCESS
【发布时间】:2011-06-29 02:37:12
【问题描述】:
我将视图控制器设置为局部变量 ASIHTTPFormDataRequest request 的委托。
但是,在请求完成之前点击“返回”,会弹出并释放视图控制器。因此,当请求完成并将消息-requestDidFinish: 发送给现在不存在的委托时,应用程序崩溃并出现EXEC_BAD_ACECESS 异常。
我该如何解决这个崩溃?
我能想到的解决此问题的一种方法是在导航控制器弹出后立即将代理设置为 nil。但是,如果这是解决方案,我该怎么做? (ARC 的 weak 引用现在会很好。)
我能想到的另一种方法是让request成为视图控制器的实例变量,并在视图控制器的dealloc方法中调用[request clearDelegatesAndCancel]; [request release];。这种方法在ASIHTTPRequest Example Code 中进行了概述,但我被告知最好使用请求本地变量而不是实例变量。而且,这个特定的视图控制器是一个设置表视图控制器,有 13 个开关。为了自动保存到服务器,每次切换时,每个开关都会创建并发送一个新请求。如果我制作了 ivars,我必须制作 13 个。那是很多代码!
想法?想法?
【问题讨论】:
标签:
objective-c
delegates
asihttprequest
dealloc
exc-bad-access
【解决方案1】:
我认为第一个问题是:如果用户在按下开关后按下回,你想要发生什么? IE。是否应该取消 http 请求,或者请求到达服务器是否重要?我现在假设您确实想取消它们,因为您的问题似乎暗示了这一点。
我被告知最好做
请求局部变量而不是
实例变量
我不确定这是否是个好建议 - 您几乎总是希望请求不是局部变量,这样您就可以处理这样的情况。
对于您的情况,您可以考虑使用NSOperationQueue。
执行此操作的大致步骤是:
- 在您的视图控制器初始化中创建一个 NSOperationQueue。
- 当您要发出 http 请求时,将其添加到 ASIHTTPRequest 队列中,而不是调用 startAsynchronous
- 在dealloc中,迭代队列中的对象,为每个对象调用
[request clearDelegatesAndCancel];,然后释放队列。
这应该可以解决崩溃而不需要 13 个 ivars!
【讨论】:
-
感谢您的解决方案。这是一个诺贝尔奖和完全有效的答案,但我选择 retain the request delegate 就像 NSURLConnection 一样,因为我相信 Apple 的设计决策,它更干净,并且即使弹出视图控制器,它也允许请求继续加载,这实际上是我想要什么。