diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e7d47f9fc..1e60016913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ - Fix mismatch in UIAccessibilityAction selector method [Michael Schneider](https://github.com/maicki) [#1169](https://github.com/TextureGroup/Texture/pull/1169) - [ASDisplayNode] Expose default Texture-set accessibility values as properties. [Jia Wern Lim](https://github.com/jiawernlim) [#1170](https://github.com/TextureGroup/Texture/pull/1170) - ASTableNode init method match checks from ASCollectionNode [Michael Schneider](https://github.com/maicki) [#1171] +- Add NSLocking conformance to ASNodeController [Michael Schneider](https://github.com/maicki)[#1179] (https://github.com/TextureGroup/Texture/pull/1179) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASNodeController+Beta.h b/Source/ASNodeController+Beta.h index e5bcc29622..65150b0e59 100644 --- a/Source/ASNodeController+Beta.h +++ b/Source/ASNodeController+Beta.h @@ -11,7 +11,8 @@ #import // for ASInterfaceState protocol /* ASNodeController is currently beta and open to change in the future */ -@interface ASNodeController<__covariant DisplayNodeType : ASDisplayNode *> : NSObject +@interface ASNodeController<__covariant DisplayNodeType : ASDisplayNode *> + : NSObject @property (nonatomic, strong /* may be weak! */) DisplayNodeType node; diff --git a/Source/ASNodeController+Beta.mm b/Source/ASNodeController+Beta.mm index 201b3cfb93..05d0ba14ee 100644 --- a/Source/ASNodeController+Beta.mm +++ b/Source/ASNodeController+Beta.mm @@ -7,10 +7,11 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import #import #import #import +#import +#import #define _node (_shouldInvertStrongReference ? _weakNode : _strongNode) @@ -18,15 +19,18 @@ { ASDisplayNode *_strongNode; __weak ASDisplayNode *_weakNode; + ASDN::RecursiveMutex __instanceLock__; } - (void)loadNode { + ASLockScopeSelf(); self.node = [[ASDisplayNode alloc] init]; } - (ASDisplayNode *)node { + ASLockScopeSelf(); if (_node == nil) { [self loadNode]; } @@ -35,6 +39,7 @@ - (void)setupReferencesWithNode:(ASDisplayNode *)node { + ASLockScopeSelf(); if (_shouldInvertStrongReference) { // The node should own the controller; weak reference from controller to node. _weakNode = node; @@ -51,11 +56,13 @@ - (void)setNode:(ASDisplayNode *)node { + ASLockScopeSelf(); [self setupReferencesWithNode:node]; } - (void)setShouldInvertStrongReference:(BOOL)shouldInvertStrongReference { + ASLockScopeSelf(); if (_shouldInvertStrongReference != shouldInvertStrongReference) { // Because the BOOL controls which ivar we access, get the node before toggling. ASDisplayNode *node = _node; @@ -82,11 +89,24 @@ - (void)hierarchyDisplayDidFinish {} +#pragma mark NSLocking + +- (void)lock +{ + __instanceLock__.lock(); +} + +- (void)unlock +{ + __instanceLock__.unlock(); +} + @end @implementation ASDisplayNode (ASNodeController) -- (ASNodeController *)nodeController { +- (ASNodeController *)nodeController +{ return _weakNodeController ?: _strongNodeController; }