ASIHTTPRequest / ASIFormDataRequest - 在ARC下的块内引用请求对象 [英] ASIHTTPRequest / ASIFormDataRequest - referencing request object within blocks under ARC
问题描述
非常类似于这个问题,我正在尝试转换使用 ASIHTTPRequest
&的项目。 ASIFormDataRequest
到ARC。
Very similar to this question, I am trying to convert a project that uses ASIHTTPRequest
& ASIFormDataRequest
to ARC.
在我的视图控制器类中,我经常在完成块中引用并使用请求
对象的属性(查看响应代码,响应数据等):
In my view controller classes, I often refer to and use properties of the request
object in the completion blocks (looking at the response code, response data etc):
__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];
[request setCompletionBlock:^{
if([request responseStatusCode] == 200) ....etc
转换为ARC时,我收到警告:
When converting to ARC I get the warning:
在此强烈捕获'请求'阻止可能导致
保留周期
Capturing 'request' strongly in this block is likely to lead to a retain cycle
这样做的正确方法是什么?
What is the proper way to do this?
另一个SO用户在上一个帖子中注意到,只需添加 __ weak
就可能导致请求在完成之前被释放块,我认为是真的。
Another SO user notes in the previous thread that simply adding __weak
may cause the request to be released before the completion of the block, which I believe to be true.
如何在ARC下的完成/失败块中正确引用这些属性?
How can I properly reference these properties in completion/failure blocks under ARC?
推荐答案
(我读了你对其他问题的评论)
(I read your comment to the other question)
用<$实现了几个模块之后c $ c> ASIHTTPRequest ,我了解到最好的方法是保持对您的请求对象的 strong
引用。在您的情况下,您可以这样做:
After implementing a few more modules using ASIHTTPRequest
, I learned that the best way was to keep a strong
reference to your request object. In your case, you can do:
self.request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];
__weak ASIFormDataRequest *weakRequest = self.request; // __block directive not needed since we only access the instance's properties.
[self.request setCompletionBlock:^{
if([weakRequest responseStatusCode] == 200)
// ...
这样你甚至可以在启动请求后控制 self.request
(例如取消)。当你准备好发布你的请求时,你可以做 self.request = nil;
,可能在你的完成块内或 self.request
的父对象的清理方法。
This way you can still control self.request
even after you start the request (e.g. for cancelling). You can do self.request = nil;
when you're ready to release your request, maybe inside your completion block or self.request
's parent object's cleanup methods.
更新:
如果您的目标是iOS 5之前的版本,那么共同点就是:使用 __ unsafe_unretained
而不是 __弱
。这没关系,因为查看 ASIHTTPRequest.m
,这些块 nil
'在其 dealloc()
(即它们不应该被执行)。虽然我还没有测试过,所以请确保仍然启用NSZombies进行测试。
If you're targeting pre-iOS 5, then the common ground stands: use __unsafe_unretained
instead of __weak
. This is OK because looking at ASIHTTPRequest.m
, the blocks are nil
'ed out in its dealloc()
(i.e. they shouldn't get executed). Although I haven't tested that yet, so make sure to still test with NSZombies enabled.
注意:
取消 ASIHTTPRequest
对象的唯一安全方法是调用其 clearDelegatesAndCancel
方法。当我刚刚使用普通的取消
一个时,我被一些讨厌的错误所困扰。
The only safe way to cancel an ASIHTTPRequest
object is to call its clearDelegatesAndCancel
method. I've been bitten by some nasty bugs when I was just using the plain cancel
one.
这篇关于ASIHTTPRequest / ASIFormDataRequest - 在ARC下的块内引用请求对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!