I finally figured out weakSelf and strongSelf

One problem with using blocks and asynchronous dispatch is that you can get into a retain cycle – the block can retain ‘self’, sometimes in mysterious ways. For instance, if you reference an ivar directly, what appears in the code is ‘theIvar’, the compiler generates ‘self->theIvar’. Thus, ‘self’, as a strong variable, is retained, and the queue retains the block, and the object retains the queue.

Apple recommends first assigning ‘self’ into a weak automatic variable, then referencing that in a block (see 1). Since the block captures the variable along with its decorators (i.e. weak qualifier), there is no strong reference to ‘self’, and the object can get dealloced, and at that moment the weak captured variable turns to nil.

__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
[weakSelf doSomething];
} );

Thinking about this, it occurred to me that ‘weakSelf’ might turn to nil in the middle of ‘doSomething’, but after a few posts on the xcode list, I was given a reference to a clang document that explicitly states that any object within an expression is retained for the complete expression, and only released thereafter (see 2). Whew!

But how about:

__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
[weakSelf doSomething];
[weakSelf doSomethingElse];
} );

Well, in this case, its possible for ‘weakSelf’ to be non-nil for the first method, but not for the second. Hmmm – the above is a simple example, most real code would get much more complex with other usages of ‘weakSelf’.

Apple calls this second example ‘non-trivial’ (see 1), and does what first seems like a bizarre set of steps: first create the ‘weakSelf’ object, then assign that to a ‘strongSelf’:

__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
__typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
} );

or in Swift:

dispatch_async(dispatch_get_main_queue()) { [weak self] in
if let strongSelf = self {
//…
}
}
// See “Resolving Strong Reference Cycles for Closures” in The Swift Programming Language

I looked and looked at this trying to reason it out (guess I’m just slow). Finally, the light bulb lit, and I figured it out! When the block runs, it’s only captured ‘weakSelf’. At the instant the block starts up, ‘weakSelf’ is either ‘self’, or it’s nil. Your code (as Apple’s example does) can test to see if ‘strongSelf’ is set, and if so you can use ‘strongSelf->theIvar’ or the more normal ‘strongSelf.someProperty’ (the latter works fine with nil messaging, the former will crash if ‘strongSelf’ is nil).

If ‘weakSelf’ is equal to ‘self’, then ‘strongSelf’ retains it, and it stays retained until the block returns, when its released. It’s all or nothing.

I felt really good finally getting this, and its making my coding of blocks much easier.

NOTE:

If you’re puzzled by the use of __typeof__(self), it’s a non-standard clang macro that turns into the class of the parenthesized object, and was taken from GCC. The nice thing about using it is that you can make this line a Code Snippet (mine is called ‘WeakSelf’), and you don’t have to continually adjust the class type.

1) “Programming With ARC Release Notes, search for “For non-trivial cycles, however, you should use”

2) http://clang.llvm.org/docs/AutomaticReferenceCounting.html :

For __weak objects, the current pointee is retained and then released at the end of the current full-expression. This must execute atomically with respect to assignments and to the final release of the pointee.

46 thoughts on “I finally figured out weakSelf and strongSelf

  1. David, This is awesome & the website is awesome, Everything is so cool. You make the website so amazing. I will decorate my wordpress later, mine is plain.

    • The logic is the same. When the next level deep is created it captures, and then when executed the same issues apply. It should be no different that the first capture. Note that a block that creates a block is processed as the first block created, then executed, and only when that code executes is the second block created. Obviously you’d want to capture references one level above you and not ‘self’ from the top level no block code.

  2. How about an example when there is a call back to main queue from dispatch like this:

    __weak typeof (self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    typeof (self)strongSelf = weakSelf;
    [strongSelf doTheJob];

    dispatch_async(dispatch_get_main_queue(), ^{
    //[strongSelf refreshUI] or [weakSelf refreshUI] or [self refreshUI]
    }
    });

    Which call is right?

    Thanks!

    • So lets look at the final section:

      typeof (self)strongSelf = weakSelf;
      // At the time of the above assignment statement, weakSelf could be nil, meaning strongSelf would be nil too.
      // NOTE: strongSelf is not going to go away now (if it was not nil).
      // Actually, I believe even if you use weakSelf in a method call, it gets retained for the life of that message so in this case weakSelf is probably not needed
      // weakSelf is still valid, as strongSelf is keeping it alive in all cases
      [strongSelf doTheJob];
      // strongSelf could go away now if not referenced further. If it had been valid, but the original "self" is no longer around, then weakSelf would go to nil

      // You could add a test in this block too, just after the assignment to strongSelf: if(strongSelf) { [strongSelf doTheJob]; dispatch_async...as below

      dispatch_async(dispatch_get_main_queue(), ^{
      // You want a weak reference here so as to not overly keep "self" alive
      // standard format would be to re-use your above construct
      typeof (self)strongSelf = weakSelf;
      [strongSelf refreshUI];
      }

      • Hi ,I still don’t know why need a strong self yet , because I think weak self is point to self or nil , both will be ok when invoke method. So what’s the point of using strong ivar to retain the weak self ?

      • The whole purpose of this blog is to explain the reason. If you cannot understand this post I’m sorry but I cannot make it any simpler or clearer – google it or look on Stack Overflow for different wording on the same issue.

      • uh ~~~sorry for my stupid:)~~the only thing that using strong reference to weak self is to avoid self be deallocated during the block executing. but if self is being deallocate before the block get execute , the use of strong reference to weak self is useless, am i right now?

      • Did you read the article after “Finally, the light bulb lit”? The block itself has a weak reference to self, and thus no retain cycle. Only when the block starts running does it try and convert the weak reference to a strong one. If at that moment ‘self’ is still valid does it then create a strong reference, and hold it long enough to complete what the block needs to do, then the strong self is released.

        If just after the block has converted the weak reference to strong, ‘self’ is finally released by all other objects, well – the block’s strong reference will keep it alive til the block returns.

        In all but pathological cases, this is never going to occur. Situations where it might are where you have a view controller with a block, and that view controller has started some activity, but the user hits the back button and the view controller is going away while in the middle of doing something. In this case, you might have an ivar that says ‘cancelAllOperations’ and set it when the user hits ‘Back’, and have all block operations that just after getting a strong self reference, check to see if they should proceed or not.

  3. Fantastic article, and I have used your format quite a bit by now. In a project I am working on at the moment with other people, I’m seeing the following being used:

    __block typeof(&*self) bSelf = self;

    And then inside the blocks it just uses bSelf.

    How does that compare to what you are recommending here?

    Thanks for any clarification,
    Erik

    • Hmmm not quite sure why &* is needed, but this is of course different. The __block will strongly retain self for the scope of self. What I have is a series of auto variables that either are strong with limited scope, or weak. Note that Xcode 5.1 now issues a warning if you use a weak variable more than once, which helps to point out places where you haven’t properly annotated a variable. In my examples, at any point the weak variable might be nil, and a strong variable initialized to nil is nil, and so will start and end that way, and nothing “bad” will happen. You just cannot access an ivar with a nil self, as that results in an offset off 0 which will cause an exception.

  4. Thanks for this clear explanation. As far as I can tell, it is only necessary to do this when `self` holds a strong reference to the block. Otherwise there shouldn’t be an issue with retain cycles. Is that correct?

    • Normally you will get a warning in Xcode when you do something that’s likely to create a retain cycle, but not always. The big no-no is having a strong block ivar, creating a block that references self, then saving that block in the ivar.

      There is no simple yes/no to your question – it gets tricky when blocks get saved and passed around – you have to think about it in those cases.

  5. Yeah I’ve seen that warning on occasion. In the case you describe, is the retain cycle happening on the strong ivar though or on self? The reference in both cases is pointing to the ivar, not to self. Unless ARC actually increases the retain count for self when you access its strong ivars?

    • The issue is that once the block retains the block owner, there is no way to release the owning object, thus the block never gets released during dealloc. This retain cycle can only be solved by (somehow) having some other object release the block first. This is the same classic retain cycle that you see when a delegate object retains the delegate.

      • Well, if `self` isn’t retaining the block, then the block will get dealloc’d when it goes out of scope, and the reference count for the retained owner within the block will get decremented. So as far as I can tell, the retain cycle can only happen when the block is strongly referenced by something the block is strongly referencing. In other words, if you have a `self.myBlock` ivar or you store the block in an `NSOperation` ivar, or something like that. Unless I am misunderstanding…

    • Jamie, when you reference an ivar, there is an implicit reference to `self` (e.g. referencing some ivar called `x` is actually equivalent to referencing `self->x`).

  6. Hey Guys,
    Just wondering, if we do this, shouldn’t we do the same thing with UIView:animationWithBlock… ? because a block is a block, isn’t it?

    It says another thing related to blocks.

    http://prntscr.com/49rfs2

    Warms Regards,
    Fernando

    • No, because the block will get executed immediately, and the view cannot get released before the block completes. The whole issue with retaining self has to do with creating a block that persists – its saved in an ivar until such time as its needed. Blocks that are created, run, then released do not cause problems.

      • Sorry, your article is misleading.
        There’re no retain cycles when GCD is involved.
        Read Jamie Forrest’s last reply again.

      • Interesting. So don’t argue with me, argue with Apple and their tech article I referenced that explicitly tells you how to avoid these cycles. I can only go on what they tell us. if as you say its all bogus, don’t argue with me, argue with them!

  7. Pingback: 1Password App Extension for iOS 8 | AskmeBoy

  8. Another great example:

    dispatch_async {

    [strongself callAMethod];
    }

    – (void)callAMethod
    {
    self.doStuf…
    }

    What is with self in a “callAMethod” method? Does is cause a retain cycle or is this “self” in context of dispatch_async and is actually “strongself” ?

    • The last code block has been reproduced in Swift. Its actually easier to understand and write too!

      Here is a bit of code I used to test it (you can try it out in a test project):

      class Foo : NSObject {
      var name: String?
      var title: String?
      }

      var foo: Foo! = Foo()
      foo.name = “Me”
      foo.title = “Head Cheese”

      var closure: () -> Void = { [weak foo] in
      if let strongFoo = foo {
      println(“name=\(foo?.name)”)
      println(“title=\(foo?.title)”)
      }
      }

      closure()
      foo = nil
      closure()

  9. In swift, you can declare self as unowned instead of weak, that means it can’t be nil inside the block. So if you try to do “if let strongSelf = self” gives an error. I wonder if strongSelf is needed in swift or when could be unowned.

    • Right, so if its unowned it will never become nil. So no need for the “if let strongSelf = self” code. I personally am not confident in understanding every edge case in iOS or OS X, and thus will continue to use the ‘[weak]’ qualifier. Don’t you hate getting crash reports that only occur in 1% of your users, and that crash in some bizarre place that is impossible to find?

  10. Pingback: Demystifying Retain Cycles in ARC | Digital Leaves

  11. Pingback: ARC中retain cycle揭秘 | 生活茶馆儿

  12. Pingback: ARC: weakSelf Caveats | Lantean

  13. Pingback: 禅与 Objective-C 编程艺术(下) | theqiong

  14. Why is self in the first part “__typeof__(self) …” not causing a retain cycle?
    Should it not be ”’__typeof__(weakSelf) strongSelf = weakSelf; ”’ in order to not be a retain cycle?

    • Because this is a complier directive – its not really holding onto self. The compiler is told to get the TYPE of item from “self”. It would probably work to use weakSelf as well, but I never tried it. Both should have the same type.

  15. As you said ‘At the instant the block starts up, ‘weakSelf’ is either ‘self’, or it’s nil.’ I want know when weakSelf is nil .

  16. I have a question. In your example above:

    __weak __typeof__(self) weakSelf = self;
    dispatch_group_async(_operationsGroup, _operationsQueue, ^
    {
    __typeof__(self) strongSelf = weakSelf;
    [strongSelf doSomething];
    [strongSelf doSomethingElse];
    } );

    If I have a doSomething method that looks like this:

    – (void)doSomething {
    NSLog(“%@”, self.someProperty);
    }

    Does self from the method body (once self.someProperty is accessed) refer to strongSelf reference or the actual self object and thus creating the retain cycle again?

    • Since you have gotten a strongSelf reference, when that method call is invoked, its strongSelf. But remember, strongSelf is actually self in this case. This whole technique is really to keep a weak reference to self, and when the time comes, determine if self is still alive – if so then self is retained, the method involved, then self immediately released.

      This same technique is still needed in Swift! People know its a pain and I believe effort is being made to come up with a better idea, but right now you still need this!

  17. Hi,

    One thing I don’t quite get on this weakself/strongself business: Yes there is a retain cycle of self retains queue, queue retains block, block retains self. However, the cycle is broken when the block gets executed and goes out of scope. At that time, block releases its ref on self, queue releases its ref on block. And self can eventually release its ref on the queue.

    Unless self holds an iVar to the block, in which case the weakself/strongself is necessary. But why doing this everywhere? Seems abusive to me. Am I missing something?

    Thanks.

    Zee

    • As you say, its a chain. If the block is submitted to a queue with no referencing ivar, then self can get released – when the block runs it will just exit as there is no strongSelf. You only need this dance if your block is not strongly referenced by the object, can execute at some time in the future, and there is no guarantee that the “self” object is still around. If you have a singleton or viewController that will never be dismissed then you don’t need this.

  18. Thanks for the response.

    what I meant was, the retain cycle is only of concern if it stays there forever. the block is meant to be run in the future, and it will go out of memory after it’s executed. when the block goes out of memory, the cycle is broken and no memory will be leaked. the cycle will only stay as long as the block itself.

    so regardless of whether my block references ivar or not, as long as the block stays in memory temporarily, the retain cycle should not be a concern. it is only a concern if the block is held by an ivar of self, which is rarely the case in my experience.

  19. I disagree with your term “retain cycle” – that implies two objects each holding strong references to the other. The block is not a persistent object in that sense – its a temporary item that runs its course then frees itself by finishing. So I think of it as having this weak reference, and when it comes alive, if that reference is still valid, retains it, does its work, then releases itself thus releasing the temporarily retained object. This is my personal way of thinking about it.

  20. I do not disagree with you. My question is, why bother with all this dance at all time? The point of this dance is to avoid a possible “persistent retain cycle” that can cause memory leak, right? The possible “persistent retain cycle” is only possible when the block is being held by self as an ivar, in which case the block stays in memory even after its execution and it could keep holding on to self. The StrongSelf as a local variable solves this cycle since the local variable goes out of scope after block’s execution.

    To my understanding, this “nice dance” is only necessary in that particular case. Doing that whenever a block is being dispatched is kind of abusive. At least that’s my understanding, or may I am missing something.

  21. There are many iOS APIs that take blocks which get run after some activity is finished – Camera, Photos APIs for sure. You had that off to the API then the user forces some action that causes the view controller to give up the UI and it gets released. Then the API finishes.

  22. Hm … in those cases, doing the weakself/strongself dance keeps the block from accessing the view controller after user has essentially given up his attention to the view. This is a good point. Thanks for pointing this out. In a real app though, depending on the actual case, sometime (could be rare, I agree) you may want the block to access the self object in that scenario to be able to preserve some data.

    Nevertheless, very insightful discussion. Thanks.

Leave a reply to Brandon Butler Cancel reply