13

I'm studying ARC. And now about zeroing weak pointer. OK I understood all the features. The semantic of weak reference is just same with weak reference of GC system, but you know, Objective-C doesn't use GC (except special case) so I can't understand how this works.

I'm a little complicated guy, so I need to know underlying implementation principal to accept the feature to use. But the problem is it's very hard to find document which describes the principal of zeroing-weak pointer :(

IMO, the only way to make this work is tracking and keeping all pointers referencing itself at runtime, and setting them all nil when its referencing count becomes 0. But this looks too heavy and stupid. I believe a lot better solution used in actual ARC implementation.

Can you help me to find the documentation? Or direct description would be more great!

eonil
  • 83,476
  • 81
  • 317
  • 516

2 Answers2

19

It's explained here:

http://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html

Spoiler:

It works pretty much how you'd think. Every class maintains a set of addresses of weak pointers that are pointing to it, and when its dealloc is called it sets them all to zero.

It may seem dumb, but it's fast because there's no "tracking" involved, ARC just inserts the code to add a pointer to that set every time the object is assigned to a new weak reference.

It's actually much more efficient than the trickery involved in Garbage collection, which basically involves wading through the heap on a background thread looking for pointers and keeping stock of what they're pointing to.

Nick Lockwood
  • 40,865
  • 11
  • 112
  • 103
  • 2
    In fact, under ARC, the compiler emits code to call functions like `objc_storeWeak` and `objc_loadWeakRetain`. These functions are a documented API: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime – rob mayoff Jan 14 '12 at 04:44
  • Yes, and those functions are how it adds and removes the weak pointers from the set stored in the object, as I stated when I said "ARC just adds the code to add a pointer to that set every time the object is assigned to a new weak reference" – Nick Lockwood Jan 15 '12 at 09:47
  • Do you know if the weak pointer is zero'ed at the moment the reference count of the object drops to 0, or when it is de-alloced? I ran into a problem now with an "assign" pointer where the referenced object is re-used, but still its dealloc is called, because its reference count dropped to 0 in between. I was wondering whether a zero-ing weak pointer would solve that. – fishinear Mar 07 '13 at 08:35
  • That's the same thing (dealloc is called when refcount goes to zero). In your example, a weak pointer would be zeroed when that happens, however as assign pointer would continue to point at the object in memory, which would continue to work for some indeterminate time until it gets overwritten by another object, at which point accessing it would crash. – Nick Lockwood Mar 07 '13 at 15:24
  • @NickLockwood would it be possible to access/see the addressees of the weak pointers? – Rui Peres May 10 '13 at 08:36
  • If I understand this, the compiler adds `objc_storeWeak` and `objc_loadWeakRetain` as needed to track weak refs in a table within each object. Presumably the `dealloc` method (also emitted by the compiler) iterates this table to zero the refs. So why is runtime support required? "Zeroing weak refs" is only supported in iOS5 and above. – David Gish Aug 02 '13 at 18:28
  • I believe the issue is that they had to modify the existing (precompiled) framework classes to support being weakly referenced. Not clear why exactly but in Mac OS 10.7 for example it supports weak refs but you can't weakly reference an NSViewController or the app crashes. – Nick Lockwood Aug 04 '13 at 07:30
  • 1
    ARC rules! Death to GC. – devios1 Aug 09 '13 at 18:48
  • If I implement dealloc, are the weak references to my object still valid or are they already zeroed when my dealloc runs? – Nicolas Miari Dec 19 '13 at 08:55
  • 1
    They're still valid (I believe). – Nick Lockwood Jan 02 '14 at 20:43
  • I'm curious, what happens when an object that contains a weak pointer is deallocated? Shouldn't the weak target be notified that one of the weak pointers no longer exists and so it shouldn't bother zeroing it? – mojuba Jan 30 '14 at 21:02
  • @mojuba yes, that's exactly what happens. On dealloc, an object containing weak pointers will remove them from the internal mapping table that their target back to them. – Nick Lockwood Jan 30 '14 at 23:23
2

Implemented by a global hash table in runtime. Apple source: https://opensource.apple.com/source/objc4/objc4-647/runtime/objc-weak.mm

liruqi
  • 1,524
  • 15
  • 12