diff --git a/Source/ASDisplayNode+Layout.mm b/Source/ASDisplayNode+Layout.mm index fb80ea313..e446cf6b6 100644 --- a/Source/ASDisplayNode+Layout.mm +++ b/Source/ASDisplayNode+Layout.mm @@ -912,7 +912,7 @@ - (void)_locked_setCalculatedDisplayNodeLayout:(std::shared_ptrlayout.size.height >= 0.0); // Flatten the layout if it wasn't done before (@see -calculateLayoutThatFits:). - if (ASDisplayNode.shouldStoreUnflattenedLayouts) { + if ([ASDisplayNode shouldStoreUnflattenedLayouts]) { _unflattenedLayout = displayNodeLayout->layout; displayNodeLayout->layout = [_unflattenedLayout filteredNodeLayoutTree]; } diff --git a/Source/ASDisplayNode.h b/Source/ASDisplayNode.h index b98619dd4..70bb3a4e2 100644 --- a/Source/ASDisplayNode.h +++ b/Source/ASDisplayNode.h @@ -554,14 +554,25 @@ extern NSInteger const ASDefaultDrawingPriority; @interface ASDisplayNode (Debugging) /** - * Whether ASDisplayNode should store their unflattened layouts. The layout can be accessed via `-unflattenedCalculatedLayout`. - * Flattened layouts use less memory and are faster to lookup, while unflattened ones are useful for debugging - * because they reserve original information. + * Set to YES to tell all ASDisplayNode instances to store their unflattened layouts. * - * Defaults to NO. + * The layout can be accessed via `-unflattenedCalculatedLayout`. + * + * Flattened layouts use less memory and are faster to lookup. On the other hand, unflattened layouts are useful for debugging + * because they preserve original information. */ + (void)setShouldStoreUnflattenedLayouts:(BOOL)shouldStore; +/** + * Whether or not ASDisplayNode instances should store their unflattened layouts. + * + * The layout can be accessed via `-unflattenedCalculatedLayout`. + * + * Flattened layouts use less memory and are faster to lookup. On the other hand, unflattened layouts are useful for debugging + * because they preserve original information. + * + * Defaults to NO. + */ + (BOOL)shouldStoreUnflattenedLayouts; @property (nonatomic, strong, readonly, nullable) ASLayout *unflattenedCalculatedLayout; diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index f82d49a20..141086103 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -82,7 +82,7 @@ @implementation ASDisplayNode @synthesize threadSafeBounds = _threadSafeBounds; static BOOL suppressesInvalidCollectionUpdateExceptions = NO; -static BOOL storesUnflattenedLayouts = NO; +static std::atomic_bool storesUnflattenedLayouts = ATOMIC_VAR_INIT(NO); + (BOOL)suppressesInvalidCollectionUpdateExceptions { @@ -1042,7 +1042,7 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize // Return the (original) unflattened layout if it needs to be stored. The layout will be flattened later on (@see _locked_setCalculatedDisplayNodeLayout:). // Otherwise, flatten it right away. - if (! storesUnflattenedLayouts) { + if (! [ASDisplayNode shouldStoreUnflattenedLayouts]) { layout = [layout filteredNodeLayoutTree]; } @@ -3296,16 +3296,17 @@ @implementation ASDisplayNode (Debugging) + (void)setShouldStoreUnflattenedLayouts:(BOOL)shouldStore { - storesUnflattenedLayouts = shouldStore; + storesUnflattenedLayouts.store(shouldStore); } + (BOOL)shouldStoreUnflattenedLayouts { - return storesUnflattenedLayouts; + return storesUnflattenedLayouts.load(); } - (ASLayout *)unflattenedCalculatedLayout { + ASDN::MutexLocker l(__instanceLock__); return _unflattenedLayout; } diff --git a/Source/Layout/ASLayout.h b/Source/Layout/ASLayout.h index 83ff30095..82cd9d605 100644 --- a/Source/Layout/ASLayout.h +++ b/Source/Layout/ASLayout.h @@ -177,11 +177,17 @@ ASDISPLAYNODE_EXTERN_C_END @interface ASLayout (Debugging) /** - * Set to YES to tell all ASLayout instances to retain their sublayouts. Defaults to NO. - * Can be overridden at instance level. + * Set to YES to tell all ASLayout instances to retain their sublayout elements. Defaults to NO. + * Can be overridden at instance level. */ + (void)setShouldRetainSublayoutLayoutElements:(BOOL)shouldRetain; +/** + * Whether or not ASLayout instances should retain their sublayout elements. + * Can be overridden at instance level. + */ ++ (BOOL)shouldRetainSublayoutLayoutElements; + /** * Recrusively output the description of the layout tree. */ diff --git a/Source/Layout/ASLayout.mm b/Source/Layout/ASLayout.mm index 4cab4c086..ddc0fb279 100644 --- a/Source/Layout/ASLayout.mm +++ b/Source/Layout/ASLayout.mm @@ -76,11 +76,16 @@ @implementation ASLayout @dynamic frame, type; -static BOOL static_retainsSublayoutLayoutElements = NO; +static std::atomic_bool static_retainsSublayoutLayoutElements = ATOMIC_VAR_INIT(NO); + (void)setShouldRetainSublayoutLayoutElements:(BOOL)shouldRetain { - static_retainsSublayoutLayoutElements = shouldRetain; + static_retainsSublayoutLayoutElements.store(shouldRetain); +} + ++ (BOOL)shouldRetainSublayoutLayoutElements +{ + return static_retainsSublayoutLayoutElements.load(); } - (instancetype)initWithLayoutElement:(id)layoutElement @@ -125,7 +130,7 @@ - (instancetype)initWithLayoutElement:(id)layoutElement } _flattened = NO; - self.retainSublayoutLayoutElements = static_retainsSublayoutLayoutElements; + self.retainSublayoutLayoutElements = [ASLayout shouldRetainSublayoutLayoutElements]; } return self;