diff --git a/Source/Details/_ASDisplayLayer.h b/Source/Details/_ASDisplayLayer.h index 95855c071d..11ed695781 100644 --- a/Source/Details/_ASDisplayLayer.h +++ b/Source/Details/_ASDisplayLayer.h @@ -53,11 +53,11 @@ + (dispatch_queue_t)displayQueue; /** - @summary Delegate for asynchronous display of the layer. + @summary Delegate for asynchronous display of the layer. This should be the node (default) unless you REALLY know what you're doing. @desc The asyncDelegate will have the opportunity to override the methods related to async display. */ -@property (nonatomic, weak) id<_ASDisplayLayerDelegate> asyncDelegate; +@property (atomic, weak) id<_ASDisplayLayerDelegate> asyncDelegate; /** @summary Suspends both asynchronous and synchronous display of the receiver if YES. diff --git a/Source/Details/_ASDisplayLayer.mm b/Source/Details/_ASDisplayLayer.mm index ea26490ec7..93eb2cb0eb 100644 --- a/Source/Details/_ASDisplayLayer.mm +++ b/Source/Details/_ASDisplayLayer.mm @@ -28,41 +28,16 @@ @implementation _ASDisplayLayer { - ASDN::Mutex _asyncDelegateLock; - // We can take this lock when we're setting displaySuspended and in setNeedsDisplay, so to not deadlock, this is recursive - ASDN::RecursiveMutex _displaySuspendedLock; - BOOL _displaySuspended; BOOL _attemptedDisplayWhileZeroSized; struct { BOOL delegateDidChangeBounds:1; } _delegateFlags; - - id<_ASDisplayLayerDelegate> __weak _asyncDelegate; } @dynamic displaysAsynchronously; -#pragma mark - -#pragma mark Lifecycle - -- (instancetype)init -{ - if ((self = [super init])) { - - self.opaque = YES; - } - return self; -} - -#pragma mark - -#pragma mark Properties - -- (id<_ASDisplayLayerDelegate>)asyncDelegate -{ - ASDN::MutexLocker l(_asyncDelegateLock); - return _asyncDelegate; -} +#pragma mark - Properties - (void)setDelegate:(id)delegate { @@ -70,22 +45,9 @@ _delegateFlags.delegateDidChangeBounds = [delegate respondsToSelector:@selector(layer:didChangeBoundsWithOldValue:newValue:)]; } -- (void)setAsyncDelegate:(id<_ASDisplayLayerDelegate>)asyncDelegate -{ - ASDisplayNodeAssert(!asyncDelegate || [asyncDelegate isKindOfClass:[ASDisplayNode class]], @"_ASDisplayLayer is inherently coupled to ASDisplayNode and cannot be used with another asyncDelegate. Please rethink what you are trying to do."); - ASDN::MutexLocker l(_asyncDelegateLock); - _asyncDelegate = asyncDelegate; -} - -- (BOOL)isDisplaySuspended -{ - ASDN::MutexLocker l(_displaySuspendedLock); - return _displaySuspended; -} - - (void)setDisplaySuspended:(BOOL)displaySuspended { - ASDN::MutexLocker l(_displaySuspendedLock); + ASDisplayNodeAssertMainThread(); if (_displaySuspended != displaySuspended) { _displaySuspended = displaySuspended; if (!displaySuspended) { @@ -146,8 +108,6 @@ - (void)setNeedsDisplay { ASDisplayNodeAssertMainThread(); - - _displaySuspendedLock.lock(); // FIXME: Reconsider whether we should cancel a display in progress. // We should definitely cancel a display that is scheduled, but unstarted display. @@ -157,7 +117,6 @@ if (!_displaySuspended) { [super setNeedsDisplay]; } - _displaySuspendedLock.unlock(); } #pragma mark - @@ -179,13 +138,14 @@ { if ([key isEqualToString:@"displaysAsynchronously"]) { return @YES; + } else if ([key isEqualToString:@"opaque"]) { + return @YES; } else { return [super defaultValueForKey:key]; } } -#pragma mark - -#pragma mark Display +#pragma mark - Display - (void)displayImmediately { @@ -209,7 +169,7 @@ ASDisplayNodeAssertMainThread(); [self _hackResetNeedsDisplay]; - if (self.isDisplaySuspended) { + if (self.displaySuspended) { return; } @@ -221,29 +181,15 @@ if (CGRectIsEmpty(self.bounds)) { _attemptedDisplayWhileZeroSized = YES; } - - id<_ASDisplayLayerDelegate> NS_VALID_UNTIL_END_OF_SCOPE strongAsyncDelegate; - { - _asyncDelegateLock.lock(); - strongAsyncDelegate = _asyncDelegate; - _asyncDelegateLock.unlock(); - } - [strongAsyncDelegate displayAsyncLayer:self asynchronously:asynchronously]; + [self.asyncDelegate displayAsyncLayer:self asynchronously:asynchronously]; } - (void)cancelAsyncDisplay { ASDisplayNodeAssertMainThread(); - id<_ASDisplayLayerDelegate> NS_VALID_UNTIL_END_OF_SCOPE strongAsyncDelegate; - { - _asyncDelegateLock.lock(); - strongAsyncDelegate = _asyncDelegate; - _asyncDelegateLock.unlock(); - } - - [strongAsyncDelegate cancelDisplayAsyncLayer:self]; + [self.asyncDelegate cancelDisplayAsyncLayer:self]; } // e.g. >