From a103bab00af7a60aaa1b8fb56c1b88575af8a0b2 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Wed, 27 Sep 2017 13:42:02 -0700 Subject: [PATCH] Clear ivar after scheduling for main thread deallocation #trivial (#590) * Clear ivar after scheduling for main thread deallocation After scheduling the ivar for main thread deallocation we have clear out the ivar, otherwise we can run into a race condition where the main queue is drained earlier than this node is deallocated and the ivar is still deallocated on a background thread * First clear and than schedule --- Source/ASDisplayNode.mm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 03c1a2f04..cde2f0030 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -428,8 +428,18 @@ - (void)_scheduleIvarsForMainDeallocation for (Ivar ivar : ivars) { id value = object_getIvar(self, ivar); + if (value == nil) { + continue; + } + if (ASClassRequiresMainThreadDeallocation(object_getClass(value))) { as_log_debug(ASMainThreadDeallocationLog(), "%@: Trampolining ivar '%s' value %@ for main deallocation.", self, ivar_getName(ivar), value); + + // Before scheduling the ivar for main thread deallocation we have clear out the ivar, otherwise we can run + // into a race condition where the main queue is drained earlier than this node is deallocated and the ivar + // is still deallocated on a background thread + object_setIvar(self, ivar, nil); + ASPerformMainThreadDeallocation(value); } else { as_log_debug(ASMainThreadDeallocationLog(), "%@: Not trampolining ivar '%s' value %@.", self, ivar_getName(ivar), value);