3

Usually weak references are used to avoid retain cycles in the application object graph. I understand that part. Now I would like to go a step further and understand how they work under the hood.

Searching a bit, I've read that when I'm using the __weak qualifier, the variable associated with that qualifier is registered in an autorelease pool, but what does this mean? Why is the object registered in the pool? What type of pool is used? Is it the main pool or some other specially created one?

When I use this code:

id _weak myWeakObj = [[NSObject alloc] init];

the compiler gives me a warning that I can fix with:

id _strong myStrongObj =  [[NSObject alloc] init];
id _weak myWeakObj = myStrongObj;

So, based on the previous question, what happens to the object referenced by myStrongObj? If possible, I'd like to know what the compiler's code looks like?

jscs
  • 63,694
  • 13
  • 151
  • 195
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
  • 1
    The actual intermediate (post-ARC) step isn't really available as source. You'd have to look at the assembler to see the retains and releases that are inserted. This is quite a nice question, though! – jscs May 22 '12 at 23:16
  • 1
    Where have you read about autorelease pool and __weak? That's not the case. It's all handled by the Objective-C runtime basically. I shall try to formulate a concise answer shortly... – mattjgalloway May 22 '12 at 23:22
  • @JacquesCousteau Thank you for upvoting and fixing the title. How can see retains and release in assembler? Thanks. – Lorenzo B May 23 '12 at 07:49
  • 1
    See http://stackoverflow.com/questions/10429857/could-we-see-what-the-arc-correct-to-our-code-in-the-compile-time – jscs May 28 '12 at 06:20

1 Answers1

5

The following is your friend:

And also the source for the Objective-C runtime:

In particular, take a look at:

If you look at objc_initWeak and objc_destroyWeak as per the 1st link talks about then you'll see how it works "under the hood". The guts is in weak_register_no_lock for registering a weak reference and in weak_unregister_no_lock for unregistering a weak reference.

I'll leave it up to you to go through and see all the intricacies around how it actually works :-).

mattjgalloway
  • 34,792
  • 12
  • 100
  • 110
  • So, when I'm using `_weak` no autorelease pool is involved, is it true? Or maybe is there the chance that the compiler adds some magical instruction that creates it? With **That's not the case** are you referring to my code snippet? – Lorenzo B May 23 '12 at 08:13
  • 2
    Autorelease pools have no bearing on `__weak`. There may still be an autorelease pool in play, yes. Infact when you load a weak reference (see `objc_loadWeak`) it retains and autoreleases the object for instance. But you don't need to worry about the autorelease pool here - it has no bearing on how a `__weak` variable works. – mattjgalloway May 23 '12 at 09:44
  • Thank you very much for your reply. Last question. In `objc_loadWeak`, there is written that *if object is registered as a __weak object, and the last value stored into object has not yet been deallocated or begun deallocation, retains that value and returns it.* Could you explain what does it mean **if object is registered as a __weak object, and the last value stored into object has not yet been deallocated or begun deallocation, retains that value and returns it.**? Thank you again. – Lorenzo B May 23 '12 at 12:55
  • 3
    It means that it'll retain the object and return that object if and only if the object has not been deallocated or is in the process of being deallocated. i.e. it'll return you a valid object always, or nil. – mattjgalloway May 24 '12 at 07:55
  • @flexaddicted, but why compiler retains that object and returns it if we explicitly used __weak qualifier? – AndrewShmig May 01 '13 at 18:04