I know that when we use block we should use weakSelf to avoid retain cycle.But I saw there is a strongSelf in block sometimes.
What confused me are:
why must change weakSelf to strongSelf?
if we don't change weakSelf to strongSelf what terrible thing would happen?
when should we change weakSelf to strongSelf?
Hope someone can give an exact example.
Thanks in advance.
why must change weakSelf to strongSelf?
Sometimes you want your block to NOT execute if the reference to self is already nil (user dismissed the view). This is why you first use weak references. (COMMON CASE)
However, sometimes you want your block to finish executing ensuring all the things its referencing are alive, but only if "self" is still alive once the block has started. In this case you make the block convert the weak reference into strong. (RARE CASE)
if we don't change weakSelf to strongSelf what terrible thing would happen?
If the block started executing while self is alive (allowing it to begin) but gets deallocated in the middle of the processing (think of a time consuming function such as image processing), and then the block accesses a resource from self (which no longer exists) it will crash.
when should we change weakSelf to strongSelf?
Almost never. The only example I can think of is when your block absolutely needs the resources from "self" once it has begun executing.
There's a more detailed explanation in this answer:
Strong reference in the block, it will be retained?
The only reason to capture self, as a weak or strong reference, in a block is because the block uses it in some way.
When self has been captured weakly how it is used will determine when, and if, you need to make a strong copy first.
If the block is going to use the captured reference multiple times then a strong copy should always be made, this insures the reference stays alive across all the uses within the block and avoids the cost of loading a weak reference multiple times.
For example, if the block's function is dependent on whether self still exists then it would be usual to start by making a strong reference and testing it. Something along the lines of:
__weak __typeof(self)weakSelf = self;
myBlock = ^{
// make local strong reference to self
__typeof(weakSelf) strongSelf = weakSelf;
// check if self still exists and process accordingly
if (strongSelf)
{
// do whatever is needed if "self" still exists
// strongSelf will keep the object alive for the
// duration of the call
}
else
{
// do whatever, if anything, is needed if "self" no longer exists
}
});
However if the block's operation only optionally requires the use of the object referenced by self then a strong copy may never be made.
HTH
In any case you need the "self" after the callback return - it is never wrong to turn weak self to strong self, in worst case - just extra code. but the opposite is not true.
here is a very simple example where you indeed need a strong ref.
__weak typeof(self) weakSelf = self;
[self.bgQueue1 addOperationWithBlock:^{
[weakSelf doSomeMagic:weakSelf.importentArr arg:number];
if (weakSelf.importentArr.count == 10){
//we will have crash(or other unpredictable results) if weakSelf will turns to nil
[DataBaseClass save:weakSelf.importentArr];
}
}];
Related
I noticed Apple's documentation saying we need to avoid strong reference cycles when capturing self.
The block in the example is a property of self.
But what if I put a block as a local variable in a dispatch_async statement?
In this case, it will not create a retain cycle even if I directly call a method of self, right?
Is the following code generating weakSelf required in this article?
// your code
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doThis];
[strongSelf doThat];
[Manager.sharedInstance updateSuccessCount];
}
});
// more code
In the example given, using dispatch_async, there would be no retain cycle, so it would be safe to capture self strongly here. The only difference would be that if self were released by everything else between when this dispatch_async was called and when the block actually ran, it would slightly delay the actual deallocation of self for that brief time, and could affect which thread the deallocation actually occurs on as well. But in general there's no harm in doing it either way when using dispatch_async.
One case where you may want to do it the way your example is written above is if the code run in the block is somewhat expensive and would only want to be done if absolutely necessary, and that it's unnecessary if self had already been released by everything else.
Another case may be if self uses a large amount of memory and gets deallocated normally right before something else starts consuming a lot of memory. In that case you may not want those two instances to be allocated at the same time.
I think I understand strong and weak keywords well, but I don't understand how it's used in the code below. This code is from SDWebImage by Olivier Poitrey available on github. I understand strong and weak keywords as is described here: Explanation of strong and weak storage in iOS5
The code below uses __weak and __strong keywords in a way that is curious to me. It is not a child-parent relationship or delegate pattern as I am used to seeing weak used. However, I'm sure that this is a pattern that is used often, as I've seen it before in other code. It sets a __weak reference before a block that runs on another thread. Then, within the block, it sets the weak reference to a strong reference.
I am certain that this good and elegant code, so I'm trying to understand it. If "self" ceases to exist before the block runs, the weak self reference will zero out. When the block runs, the strong reference will be set to zero as well. Therefore, it will know to kill the rest of the operation since self doesn't exist anymore. Did I get this right?
Now, what would happen if we didn't use __weak and __strong keywords? What if we just checked inside the block whether self == nil. Would "self" never be nil since the block copies the entire tree?
Can someone help demystify this awesome piece of code? Can someone verify or repudiate my hypotheses?
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock;
{
[self cancelCurrentImageLoad];
self.image = placeholder;
if (url)
{
__weak UIImageView *wself = self;
id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
{
__strong UIImageView *sself = wself;
if (!sself) return;
if (image)
{
sself.image = image;
[sself setNeedsLayout];
}
if (completedBlock && finished)
{
completedBlock(image, error, cacheType);
}
}];
objc_setAssociatedObject(self, &operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
The downloadWithUrl: method might take a long time. In that time, the user might decide to navigate away, eliminating the need for the SDWebImage object. To facilitate early cleanup of the object, the outer self reference is weak. This way, downloadWithUrl won't prevent the SDWebImage from being deallocated.
Of course, if you actually want to work with self, you need a strong reference. So, the on-completion block of downloadWithUrl grabs a strong reference to self. If the object goes away in this time, sself will be nil. Otherwise, it will be a valid strong reference, indicating that the SDWebImage object is still around, and the object will finish its work at this time.
I am certain that this good and elegant code, so I'm trying to understand it. If "self" ceases to exist before the block runs, the weak self reference will zero out. When the block runs, the strong reference will be set to zero as well. Therefore, it will know to kill the rest of the operation since self doesn't exist anymore. Did I get this right?
Nope, you're over thinking this quite a bit. The __weak storage qualifier is just that: a qualifier. Objects that are __weak are explicitly unretained, but they aren't just automatically set to nil if assigned from a strong variable. In fact, that would defeat the purpose of a weak variable!
Now, what would happen if we didn't use __weak and __strong keywords? What if we just checked inside the block whether self == nil. Would "self" never be nil since the block copies the entire tree?
The checking is actually unnecessary because the runtime resolves messages to nil to nil (nevertheless, it may be important to the implementation later on, who knows). You are spot on with this one: without that little "weak to strong" dance there, then self would be retained by the block, with the potential to create a pretty nasty retain cycle. Which is where I can start tying this all together:
Because we don't want the block to retain our variable, but we also want it to be strong inside the scope of the block so nothing weird happens, self is assigned to a weak pointer. When the block happens upon our weak pointer, it isn't allowed to retain it, so self's reference count stays the same, then once inside the block, we go right back to a strong self variable so the weak one is released, and we don't have to worry about it any more. Practically, this means we have a solid guarantee that self is either a value or nil throughout the entire execution of the block. Pretty neat, huh?
This question already has answers here:
How does the new automatic reference counting mechanism work?
(6 answers)
Closed 9 years ago.
I'm new to Objective C and I'm porting parts of an old (non ARC) framework to ARC. My question is, although ARC handles a lot of memory management behind the scenes now, are there any major memory management principles that I still need to be aware of to avoid leaks?
For instance I thought I read somewhere that in the 'main' function of an NSOperation subclass, the programmer should set up an 'autoreleasepool' for that function.
Probably the two biggest issues to watch for are 1) retain cycles, where x retains y and y retains x thus they're never freed. This usually happens with blocks. And 2) when using Core Foundation functions (Core Graphics etc), for example: CGImageCreate, CGImageRetain, CGImageRelease. You still need to manually manage the memory in those cases.
A common pattern to prevent retain cycles is to create a weak reference to one of the objects that would be in the cycle. (Often self). Such as this:
__weak typeof(self) weakSelf = self;
[self useBlock:^{
typeof(weakSelf) strongSelf = weakSelf;
// do something with strongSelf
}];
Notes:
a) The reason you want to create a new strongSelf inside the block, is to ensure you're retaining the weakSelf variable for the duration of the block. Otherwise, you can have cases where weakSelf will become nil part way through the block. In some cases, you may want to add a test that strongSelf still exists immediately, and if not abort the block altogether. As weakSelf could become nil before the block starts.
__weak typeof(self) weakSelf = self;
[self useBlock:^{
typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) return;
// do something with strongSelf
}];
b) You only need to do this when self will be retaining the block (in this case via something the unknown useBlock method is doing).
The programmer still needs to be 100% aware of retain/release, however, the compiler is doing 98% of the work. The 2% it can't do well is breaking retain cycle's, so it's helpful for the compiler to specify weak retention in properties or using the __weak modifier in select scenarios.
You may still setup your own #autoreleasepool's, too. The only time I've used them purposefully is in/as the body of a for loop, to force the memory to be reclaimed each iteration.
I'm reading Xcode's documentation, and here is something that puzzles me:
__block typeof(self) tmpSelf = self;
[self methodThatTakesABlock:^ {
[tmpSelf doSomething];
}];
The following is copied from the documentation:
A block forms a strong reference to variables it captures. If you use
self within a block, the block forms a strong reference to self, so if
self also has a strong reference to the block (which it typically
does), a strong reference cycle results. To avoid the cycle, you need
to create a weak (or __block) reference to self outside the block, as
in the example above.
I don't understand what does 'a weak (or __block)' mean?
Is
__block typeof(self) tmpSelf = self;
and
__weak typeof(self) tmpSelf = self;
exactly the same here?
I found another piece in the document:
Note: In a garbage-collected environment, if you apply both __weak and
__block modifiers to a variable, then the block will not ensure that it is kept alive.
So, I'm totally puzzled.
From the docs about __block
__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.
From the docs about __weak
__weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
So they are technically different things. __block is to stop your variable being copied from your external scope into your block scope. __weak is a self delimiting weak pointer.
Note I said technically, because for your case they will do (almost) the same thing. The only difference is if you are using ARC or not. If your project uses ARC and is only for iOS4.3 and above, use __weak. It ensures the reference is set to nil if the global scope reference is releases somehow. If your project doesn't use ARC or is for older OS versions, use __block.
There is a subtle difference here, make sure you understand it.
EDIT: Another piece to the puzzle is __unsafe_unretained. This modifier is almost the same as __weak but for pre 4.3 runtime environments. HOWEVER, it is not set to nil and can leave you with hanging pointers.
In manual reference counting mode, __block id x; has the effect of not retaining x. In ARC mode, __block id x; defaults to retaining x (just like all other values). To get the manual reference counting mode behavior under ARC, you could use __unsafe_unretained __block id x;. As the name __unsafe_unretained implies, however, having a non-retained variable is dangerous (because it can dangle) and is therefore discouraged. Two better options are to either use __weak (if you don’t need to support iOS 4 or OS X v10.6), or set the __block value to nil to break the retain cycle.
apple docs
Beside other answers on __block vs __weak, there is another way to avoid retain cycle in your scenario.
#weakify(self);
[self methodThatTakesABlock:^ {
#strongify(self);
[self doSomething];
}];
More Info about #Weakify #Strongify Macro
When using self in block, should use __weak, not __block as it may retain self.
In case you need strong self, then you can use like this:
__weak typeof(self) *weakSelf = self;
[self methodThatTakesABlock:^{
if (weakSelf) {
__strong typeof(self) *strongSelf = weakSelf;
[strongSelf doSomething];
}
}];
In many guide about how to use blocks and GCD, one tip is always mentioned : do not retain self in block.
The detail is when defining a block, if you reference self or a ivar of self, then self is retained by the block. So the work around is to use __block modifier to get a weakSelf or weakIvar.
But what's the harm of not doing that? If the block retains self, it should release self when the block is finished(Am I right about this?). So ultimately the reference count of self is balanced. I know if self retains the block and the block retains self, it would be a retain cycle.Neither the block and self will be deallocated. But if using GCD, self don't retain the block, why not let the block retain self?
There is no harm in retaining self unless the block stays around. If you are using GCD to execute the block and then it is removed then that is fine. It is only a problem if self has a reference to the block that it keeps around (i.e self.someBlock = ^{self.x = 2;}) because then you have a retain cycle.
Personally I like the block retaining self (if used) in GCD as you have no real control over when the block executes and it cannot be canceled, so it may execute after self is deallocated if it is not retained.