From 4482919e09d23dbd663bb5bc7249ed90b896a697 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Wed, 21 Aug 2019 15:06:24 +0100 Subject: [PATCH] Fix an issue with `WeakRef`s being over-released As an optimisation, on load of a weak reference we check if the object has already been deallocated and, if so, decrement the weak reference count and zero the pointer to the weak reference structure so that the next check is faster and doesn't need to hold locks for as long. Unfortunately, the prior implementation of this instead decremented the weak reference count and then only zeroed the pointer if the reference count reached zero. This meant that loading the same __weak pointer twice after the pointed-to object had been deallocated would decrement the reference count twice. --- arc.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arc.m b/arc.m index 719ed9d..321e532 100644 --- a/arc.m +++ b/arc.m @@ -856,8 +856,9 @@ OBJC_PUBLIC id objc_loadWeakRetained(id* addr) if (obj == nil) { // If we've destroyed this weak ref, then make sure that we also deallocate the object. - if (weakRefRelease(ref)) + if (ref != NULL) { + weakRefRelease(ref); *addr = nil; } return nil;