Explain __weak and __strong usage reasons in SDWebImage code

后端 未结 2 1872
灰色年华
灰色年华 2020-12-30 15:57

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 g

相关标签:
2条回答
  • 2020-12-30 16:34

    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.

    0 讨论(0)
  • 2020-12-30 16:58

    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?

    0 讨论(0)
提交回复
热议问题