diff --git a/AsyncDisplayKit/ASMultiplexImageNode.mm b/AsyncDisplayKit/ASMultiplexImageNode.mm index a1c6660fd6..19145359ba 100644 --- a/AsyncDisplayKit/ASMultiplexImageNode.mm +++ b/AsyncDisplayKit/ASMultiplexImageNode.mm @@ -531,7 +531,7 @@ - (void)_clearImage BOOL shouldReleaseImageOnBackgroundThread = imageSize.width > kMinReleaseImageOnBackgroundSize.width || imageSize.height > kMinReleaseImageOnBackgroundSize.height; if (shouldReleaseImageOnBackgroundThread) { - ASPerformBlockOnBackgroundThread(^{ + ASPerformBlockOnDeallocationQueue(^{ image = nil; }); } diff --git a/AsyncDisplayKit/ASNetworkImageNode.mm b/AsyncDisplayKit/ASNetworkImageNode.mm index 3ce5e4b12f..279f1bca79 100755 --- a/AsyncDisplayKit/ASNetworkImageNode.mm +++ b/AsyncDisplayKit/ASNetworkImageNode.mm @@ -378,7 +378,7 @@ - (void)_clearImage BOOL shouldReleaseImageOnBackgroundThread = imageSize.width > kMinReleaseImageOnBackgroundSize.width || imageSize.height > kMinReleaseImageOnBackgroundSize.height; if (shouldReleaseImageOnBackgroundThread) { - ASPerformBlockOnBackgroundThread(^{ + ASPerformBlockOnDeallocationQueue(^{ image = nil; }); } diff --git a/AsyncDisplayKit/ASTextNode.mm b/AsyncDisplayKit/ASTextNode.mm index 5fc9ac2919..fedcfaa091 100644 --- a/AsyncDisplayKit/ASTextNode.mm +++ b/AsyncDisplayKit/ASTextNode.mm @@ -260,7 +260,7 @@ - (void)_invalidateRenderer // actually dealloc. __block ASTextKitRenderer *renderer = _renderer; - ASPerformBlockOnBackgroundThread(^{ + ASPerformBlockOnDeallocationQueue(^{ renderer = nil; }); _renderer = nil; diff --git a/AsyncDisplayKit/Private/ASInternalHelpers.h b/AsyncDisplayKit/Private/ASInternalHelpers.h index 8f154949a6..cff8c1fc53 100644 --- a/AsyncDisplayKit/Private/ASInternalHelpers.h +++ b/AsyncDisplayKit/Private/ASInternalHelpers.h @@ -17,8 +17,15 @@ ASDISPLAYNODE_EXTERN_C_BEGIN BOOL ASSubclassOverridesSelector(Class superclass, Class subclass, SEL selector); BOOL ASSubclassOverridesClassSelector(Class superclass, Class subclass, SEL selector); + +/// Dispatches the given block to the main queue if not already running on the main thread void ASPerformBlockOnMainThread(void (^block)()); -void ASPerformBlockOnBackgroundThread(void (^block)()); // DISPATCH_QUEUE_PRIORITY_DEFAULT + +/// Dispatches the given block to a background queue with priority of DISPATCH_QUEUE_PRIORITY_DEFAULT if not already run on a background queue +void ASPerformBlockOnBackgroundThread(void (^block)()); // DISPATCH_QUEUE_PRIORITY_DEFAULT + +/// Dispatches a block on to a serial queue that's main purpose is for deallocation of objects on a background thread +void ASPerformBlockOnDeallocationQueue(void (^block)()); CGFloat ASScreenScale(); diff --git a/AsyncDisplayKit/Private/ASInternalHelpers.mm b/AsyncDisplayKit/Private/ASInternalHelpers.mm index e18b932ce9..4d4ccbbf74 100644 --- a/AsyncDisplayKit/Private/ASInternalHelpers.mm +++ b/AsyncDisplayKit/Private/ASInternalHelpers.mm @@ -52,6 +52,17 @@ void ASPerformBlockOnBackgroundThread(void (^block)()) } } +void ASPerformBlockOnDeallocationQueue(void (^block)()) +{ + static dispatch_queue_t queue; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + queue = dispatch_queue_create("org.AsyncDisplayKit.deallocationQueue", DISPATCH_QUEUE_SERIAL); + }); + + dispatch_async(queue, block); +} + CGFloat ASScreenScale() { static CGFloat __scale = 0.0;