Open yasirmturk opened 11 years ago
I think the problem could be the unsafe_unretained? __unsafe_unretained block might work better.. or you could nil req instead in the completion block to break the cycle.
same result with __unsafe_unretained __block
, however if i remove any of these it works but with the retain cycle warning
Hm. I've not had enough caffeine yet to remember all my ARC. I'd possibly recommend a __weak property for your object that you stash the request into. (Generally it's a good idea to keep hold of requests so you can cancel them if necessary.)
Or break the loop explicitly and disable the warning for that bit of code (this is the approach AFNetworking takes in it's core code!)
__weak
causes the object to become nil right in the next line...
i discovered this issue now on 7th day after submission when my app is about to be reviewed by apple guys.. i just wonder what could be more terrible than that??
Yeah, actually __weak was an obviously stupid suggestion, sorry. Told you I hadn't had my caffeine :(
Keeping a strong reference would solve it presumably. There must be something else going on though; you did disable ARC for the ASIHTTPRequest source files, right?
yes, it wont even compile otherwise
I'm assuming you've probably solved the issue by now, but just in case others are looking for potential solutions.
If you are currently targeting iOS 4.3+, you may be able to get by with just ignoring it, disabling the warning on the offending files, or even the offending lines, and just make sure you are careful with that pointer.
Disabling the pointer for specific line(s):
#pragma clang diagnostic push
#pragma clang diagnostic ignore "-Warc-retain-cycles"
// Your code
#pragma clang diagnostic pop
If you really want to get rid of the warning, I'd suggest something like the below:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
__unsafe_unretained ASIHTTPRequest *weakRequest = request;
// Keep a strong reference somewhere so you don't end up with
// weakRequest becoming a dangling pointer!
self.myRequest = request;
[req setCompletionBlock:^{
// VERY dangerous here if you do not have a strong reference to
// the operation somewhere. Since weakRequest is weak, ARC can
// (and will) deallocate the request if no one has a strong reference to it.
// iOS 4.3 does not support auto-zeroing weak pointers and this will become
// a dangling pointer.
NSLog(@"setCompletionBlock:%@", weakRequest.responseString);
}];
The best solution would be to target iOS 5.0+, if possible, instead of 4.3. In that case, you get access to ARC's auto-zeroing weak pointers (__weak); They are awesome:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
__weak ASIHTTPRequest *weakRequest = request;
[req setCompletionBlock:^{
// Make sure the request remains valid for at least this block
// by holding a local strong reference to it.
ASIHTTPRequest *localRequest = weakRequest;
// Auto-zeroing weak pointers in action! If the request is
// deallocated before we get here, weakRequest is nil and all
// you'll see in the log is 'setCompletionBlock:(null)'
NSLog(@"setCompletionBlock:%@", localRequest.responseString);
}];
i have an ARC enabled project iOS 4.3+ where i implemented ASIHTTP with code blocks..to avoid retains cycle i have to use
__unsafe_unretained
.. it workes perfect in debug mode + (release mode with Instruments) but as soon as i switch to release mode/install via TestFlight/ and try to run the it crashes at[req startAsynchronous]
;__unsafe_unretained ASIHTTPRequest *req = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]]; [req setCompletionBlock:^{ NSLog(@"setCompletionBlock:%@", req.responseString); }]; NSLog(@"starting:%@", req); [req startAsynchronous];