I discover this snippet code from company's document:
__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
// Do stuff
});
It's will be retained ?
I discover this snippet code from company's document:
__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
// Do stuff
});
It's will be retained ?
There are two reasons to capture weak
references within a block.
avoid retain cycles
create no-op situations.
The former has been discussed ad-nauseum. The second is more interesting.
Example
The block in question is a completion handler for an image download. When the download is complete, it is to be displayed in an image view.
It doesn't need to do anything if the image view has already been deallocated (say the user has switched to a new view). There is no danger of a retain cycle, because the image view has no reference to the block. However, capturing a weak
reference allows the image view to be deallocated before the block executes. Thus, if the user switches views before the image is downloaded, the block ends up doing nothing because its weak
reference has already been nil
ed. It also doesn't matter if the image view is deallocated part way through the block's execution, because it just turns operations on the image view into no-ops, instead of turning the entire block into a no-op.
Sometimes, however, the block wants the no-op behavior, but only if the reference was already nil
when it began (or reached a certain point in the code path). If, at the time the block executes, the object is live, the block has to execute in its entirety. It can't stop half-way through because the object is deallocated on some other thread.
Example
The purpose of the completion block is to add a caption, defined by a string, to the image. If the string has been deallocated already, no caption is to be added. However, if the string is still live when post-processing begins, it must remain live to avoid trying to create an attributed string with a
nil
reference, because that leads to a crash.
In this scenario, it would be proper to capture the string with a weak
reference, so it can be deallocated by some other thread (leading to no caption). However, before the string is used within the block, it must be captured strong
ly to avoid a crash when creating the attributed string.
The weak copy outside the block is enough.
__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
// silliness: __strong __typeof(weakSelf)strongSelf = weakSelf;
// Do stuff with weakSelf here
});
In fact, this is okay too:
dispatch_async(dispatch_get_main_queue(),
^{
// self self self, go ahead and mention self here
});
The thing one must not do is copy that block someplace, and mention that someplace in the block.
@property (nonatomic, strong) void (^myBlock)(void);
self.myBlock = ^void(void) {
// don't mention self here!
};
The idea is that blocks retain the objects they mention, and we're trying to avoid cycles, so object -> block -> another_object
is fine, but object -> block -> another_object -> any amount of indirection -> object
is a cycle, and that's bad.
Cycles are bad because an object can't be deallocated if it's retained elsewhere, and so the things it retains can't be deallocated. If two things retain each other, then they're both stuck, unable to be deallocated because each is retained by something.
EDIT what I misunderstood until today is that the strong copy of the weak var isn't always silly. It can be relevant, but the case where it makes sense is highly qualified).
If you use this:
__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
// Do stuff
});
Self may get deallocated while the block is being executed. So we had better to convert the weakSelf to strongSelf to ensure that self stays in memory until the block finishes execution.
After your use of __strong __typeof(weakSelf)strongSelf = weakSelf
, self will refer to local, stack variables. So It's will not be retained.