The characteristics of the weak attribute: Weak indicates that the attribute defines a nonowning relationship. When you set a new value for the weak property, the setting method neither preserves the new value nor releases the old value. Similar to assign, however, the value of the attribute is nil out when the object to which it refers is released.
How does runtime automatically set weak to nil?
The weak object is put into a hash table. Weak is dealloc when the reference count is 0. Weak is dealloc when the reference count is 0. If weak points to an object whose memory address is addr, then it searches the weak table with addr as the key, finds all weak objects with addr as the key, and sets them to nil.
Specific mechanism:
Objc_storeWeak (&weakPo, Model) function:
The objc_storeWeak function registers the memory address of the assignment object (Model) as the key value, and the memory address of the weak-modified property variable (weakPo) (& weakPo) as value, registering it in the weak table.
If Model is 0 (nil), then delete the memory address of variable (weakPo) (& weakPo) from weak table,
Objc_storeWeak (&weakPo, Model) can be understood as: objc_storeWeak(value, key), and when key changes to nil, value is set to nil.
When Model is non-nil, weakPo and Model point to the same memory address, and when Model becomes nil, weakPo becomes nil. Sending messages to weakPo won’t crash at this point: it’s safe to send messages to nil in Objective-C.
Objc /objc-weak.h code link