diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 1f41c17838..5e516fedb6 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -63,6 +63,17 @@ CGFloat ASDisplayNodeScreenScale() return screenScale; } +void ASDisplayNodePerformBlockOnMainThread(void (^block)()) +{ + if ([NSThread isMainThread]) { + block(); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + block(); + }); + } +} + + (void)initialize { if (self == [ASDisplayNode class]) { diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index 0c1a5e01e1..f64bc6d9f3 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -106,35 +106,35 @@ - (void)setImage:(UIImage *)image { - ASDisplayNodeAssertThreadAffinity(self); ASDN::MutexLocker l(_imageLock); if (_image != image) { _image = image; - [self invalidateCalculatedSize]; - [self setNeedsDisplay]; + ASDisplayNodePerformBlockOnMainThread(^{ + [self invalidateCalculatedSize]; + [self setNeedsDisplay]; + }); } } - (UIImage *)image { - ASDisplayNodeAssertThreadAffinity(self); ASDN::MutexLocker l(_imageLock); return _image; } - (void)setTint:(ASImageNodeTint)tint { - ASDisplayNodeAssertThreadAffinity(self); ASDN::MutexLocker l(_imageLock); if (_tint != tint) { _tint = tint; - [self setNeedsDisplay]; + ASDisplayNodePerformBlockOnMainThread(^{ + [self setNeedsDisplay]; + }); } } - (ASImageNodeTint)tint { - ASDisplayNodeAssertThreadAffinity(self); ASDN::MutexLocker l(_imageLock); return _tint; } @@ -281,19 +281,16 @@ #pragma mark - Cropping - (BOOL)isCropEnabled { - ASDisplayNodeAssertThreadAffinity(self); return _cropEnabled; } - (void)setCropEnabled:(BOOL)cropEnabled { - ASDisplayNodeAssertThreadAffinity(self); [self setCropEnabled:cropEnabled recropImmediately:NO inBounds:self.bounds]; } - (void)setCropEnabled:(BOOL)cropEnabled recropImmediately:(BOOL)recropImmediately inBounds:(CGRect)cropBounds { - ASDisplayNodeAssertThreadAffinity(self); if (_cropEnabled == cropEnabled) return; @@ -303,23 +300,22 @@ // If we have an image to display, display it, respecting our recrop flag. if (self.image) { - if (recropImmediately) - [self displayImmediately]; - else - [self setNeedsDisplay]; + ASDisplayNodePerformBlockOnMainThread(^{ + if (recropImmediately) + [self displayImmediately]; + else + [self setNeedsDisplay]; + }); } } - (CGRect)cropRect { - ASDisplayNodeAssertThreadAffinity(self); return _cropRect; } - (void)setCropRect:(CGRect)cropRect { - ASDisplayNodeAssertThreadAffinity(self); - if (CGRectEqualToRect(_cropRect, cropRect)) return; @@ -332,8 +328,10 @@ BOOL isCroppingImage = ((boundsSize.width < imageSize.width) || (boundsSize.height < imageSize.height)); // Re-display if we need to. - if (self.nodeLoaded && self.contentMode == UIViewContentModeScaleAspectFill && isCroppingImage) - [self setNeedsDisplay]; + ASDisplayNodePerformBlockOnMainThread(^{ + if (self.nodeLoaded && self.contentMode == UIViewContentModeScaleAspectFill && isCroppingImage) + [self setNeedsDisplay]; + }); } @end diff --git a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h index 9e18d49073..59d6b40df5 100644 --- a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h +++ b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h @@ -20,6 +20,7 @@ BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector); CGFloat ASDisplayNodeScreenScale(); +void ASDisplayNodePerformBlockOnMainThread(void (^block)()); @class _ASPendingState; diff --git a/examples/Kittens/Sample/KittenNode.m b/examples/Kittens/Sample/KittenNode.m index b269b59b10..5bb9032f90 100644 --- a/examples/Kittens/Sample/KittenNode.m +++ b/examples/Kittens/Sample/KittenNode.m @@ -138,15 +138,7 @@ static const CGFloat kInnerPadding = 10.0f; return; // set our image node's data - if (_imageNode.nodeLoaded) { - dispatch_sync(dispatch_get_main_queue(), ^{ - // once the node's view is loaded, the node should only be used on the main thread - _imageNode.image = [UIImage imageWithData:data]; - }); - } else { - // if the node hasn't loaded, we can use it on a background thread - _imageNode.image = [UIImage imageWithData:data]; - } + _imageNode.image = [UIImage imageWithData:data]; }]; }