Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix calling CALayer out of the main thread #1762

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 34 additions & 27 deletions Source/ASDisplayNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -438,36 +438,43 @@ - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body
- (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection
{
if (@available(iOS 13.0, *)) {
// When changing between light and dark mode, often the entire node needs to re-render.
// This change doesn't happen frequently so it's fairly safe to render nodes again
__instanceLock__.lock();
if (self.primitiveTraitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle) {
// When changing between light and dark mode, often the entire node needs to re-render.
// This change doesn't happen frequently so it's fairly safe to render nodes again
BOOL needsClippingCornerUpdate = NO;
CGFloat cornerRadius = _cornerRadius;
ASCornerRoundingType cornerRoundingType = _cornerRoundingType;
UIColor *backgroundColor = _backgroundColor;
if (_loaded(self)) {
CGColorRef cgBackgroundColor = backgroundColor.CGColor;
if (!CGColorEqualToColor(_layer.backgroundColor, cgBackgroundColor)) {
// Background colors do not dynamically update for layer backed nodes since they utilize CGColorRef
// instead of UIColor. Non layer backed node also receive color to the layer (see [_ASPendingState -applyToView:withSpecialPropertiesHandling:]).
// We utilize the _backgroundColor instance variable to track the full dynamic color
// and apply any changes here when trait collection updates occur.
_layer.backgroundColor = cgBackgroundColor;
}
// If we have clipping corners, re-render the clipping corner layer upon user interface style change
if (cornerRoundingType == ASCornerRoundingTypeClipping && cornerRadius > 0.0f) {
needsClippingCornerUpdate = YES;
}
}
__instanceLock__.unlock();
if (needsClippingCornerUpdate) {
[self _updateClipCornerLayerContentsWithRadius:cornerRadius backgroundColor:backgroundColor];
BOOL loaded = _loaded(self);
ASPrimitiveTraitCollection primitiveTraitCollection = _primitiveTraitCollection;
__instanceLock__.unlock();
if (primitiveTraitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle) {
if (loaded) {
// we need to run that on main thread, cause accessing CALayer properties.
// It seems than in iOS 13 sometimes it causes deadlock.
ASPerformBlockOnMainThread(^{
vovasty marked this conversation as resolved.
Show resolved Hide resolved
__instanceLock__.lock();
CGFloat cornerRadius = _cornerRadius;
ASCornerRoundingType cornerRoundingType = _cornerRoundingType;
UIColor *backgroundColor = _backgroundColor;
ASPrimitiveTraitCollection primitiveTraitCollection = _primitiveTraitCollection;
__instanceLock__.unlock();
UITraitCollection *traitCollection = ASPrimitiveTraitCollectionToUITraitCollection(primitiveTraitCollection);
UIColor *resolvedBackgroundColor = [backgroundColor resolvedColorWithTraitCollection:traitCollection];
CGColorRef cgBackgroundColor = resolvedBackgroundColor.CGColor;
if (!CGColorEqualToColor(_layer.backgroundColor, cgBackgroundColor)) {
// Background colors do not dynamically update for layer backed nodes since they utilize CGColorRef
// instead of UIColor. Non layer backed node also receive color to the layer (see [_ASPendingState -applyToView:withSpecialPropertiesHandling:]).
// We utilize the _backgroundColor instance variable to track the full dynamic color
// and apply any changes here when trait collection updates occur.
_layer.backgroundColor = cgBackgroundColor;
}

// If we have clipping corners, re-render the clipping corner layer upon user interface style change
if (cornerRoundingType == ASCornerRoundingTypeClipping && cornerRadius > 0.0f) {
[self _updateClipCornerLayerContentsWithRadius:cornerRadius backgroundColor:backgroundColor];
}

[self setNeedsDisplay];
});
}
[self setNeedsDisplay];
return;
}
__instanceLock__.unlock();
}
}

Expand Down