Reputation: 1024
I have written a sample code to make a server connection. Please find the code that I have written below.
__weak typeof(self) weakSelf = self;
self.dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
weakSelf.dataTask = nil;
NSInteger extractionResponseCode = [((NSHTTPURLResponse *)response) statusCode];
if (!error && data.length > 0 && extractionResponseCode == 200)
{
[weakSelf handleResponse:data];
}
else
{
[weakSelf handleError:error];
}
}];
After getting the response I have to call either handleResponse:
or handleError:
based on the response.
I have taken weakSelf to avoid retain cycle problem in ARC.
My problem here is inside the block weakSelf is getting as nil so neither handleResponse:
nor handleError:
methods are called.
Could you please help me how can I resolve this issue.?
Thanks in advance.
Upvotes: 1
Views: 1399
Reputation: 16660
I really wonder, why people think that you need to weakify self every time you capture it.
As the term retain cycle says, you can only have one, if you have a reference to an object that refers to the object holding the first reference (directly or via a number of other references).
So if the block context refers to self
, you have a reference cycle, if and only if the block is referred by self
. (BTW: This applies to every (strong) reference. There is nothing special about self
in Objective-C, nowhere.) You do not have that. Preventing from retain cycles is no reason to weakify self
in your case.
However, some want to weakify it, to make self
nil
in such a case. This is the intention. This can be an advantage under some circumstances: Simply think of a model object that is gone while downloading data for it. There is no reason to keep it alive.
If you do not want that, simply do not weakify self
. It is that simple.
Upvotes: 1
Reputation: 52632
The idea is that downloading data shouldn't keep your object alive. If your object goes away while the download is running (for example if the user switches from the screen causing the download to aother screen) then you should just ignore the result and throw it away, or maybe store it to a file, but you should allow self to become nil.
This has nothing to do with a reference cycle: self will go away eventually if you don't use weakSelf, but you shouldn't keep it alive longer than needed. Worst case, you might show an error alert to the user about a screen that has long gone. A failing URL request might take 60 seconds to fail, so the user might do something completely different already.
The correct way to use weakSelf is to assign it to a new variable strongSelf in your callback, then check that it is not nil. Using weakSelf directly is bad because it can become nil at any time.
Upvotes: 0
Reputation: 7552
The answer is to capture a strong reference. You don't have a retain cycle anyway, unless self
has a reference to the completion block. And the strong reference will be released anyway, when the block returns, which will break the cycle if you do happen to have one.
Upvotes: 2