We have a class that wraps NSURLConnection. It accepts a block that it calls back when it finishes loading. To give you an idea, see below. When you send a request, it saves the callback on the instance. Assume my class is named Request
// from Request.h
@property (nonatomic, copy) void(^callback)(Request*);
- (void) sendWithCallback:(void(^)(Request*))callback;
My code to use one looks something like this:
Request * request = [Request requestWithURL:url];
[request sendWithCallback:^(Request * request) {
// do some stuff
}]
My question is: what does the block do to the retain count of request
? Does it copy/retain it? Notice that I didn't put __block
in front of the definition.
I just changed something major in Request
(switched from a synchronous NSURLConnection
to async ASIHTTPRequest
), and it started deallocing almost immediately after sending (causing delegate methods to call a dealloced object). With the sync NSURLConnection
, that never happened.
I guess it makes sense that it would get dealloced with async, but how would I retain request
appropriately? If I retained it right after I created it, I'd have to release it in the callback, but the callback doesn't get called if the request is cancelled, and would create a memory leak.
what does the block do to the retain count of request? Does it copy/retain it?
No, it doesn't.
Request * request = [Request requestWithURL:url];
[request sendWithCallback:^(Request * request) {
// The request argument shadows the request local variable,
// this block doesn't retain the request instance.
}]
If the block doesn't have the request argument,
Request * request = [Request requestWithURL:url];
[request sendWithCallback:^{
// If you use the request local variable in this block,
// this block automatically retains the request instance.
}]
In this case, it would cause retain cycles (the request retains the block, the block retains the request).
Please take a look at my AsyncURLConnection class. NSURLConnection retains AsyncURLConnection instance, so you don't own AsyncURLConnection stuff by yourself.
How to use
[AsyncURLConnection request:url completeBlock:^(NSData *data) {
// Do success stuff
} errorBlock:^(NSError *error) {
// Do error stuff
}];