From a650f2f14918072540f8595755a8afd71a49a24a Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Mon, 15 Apr 2019 15:46:15 +0800 Subject: [PATCH 1/5] Remove lock of ASTextNodeRendererKey --- Source/ASTextNode.mm | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index 7995d206b..c48d36efa 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -58,17 +58,25 @@ #pragma mark - ASTextKitRenderer @interface ASTextNodeRendererKey : NSObject -@property (nonatomic) ASTextKitAttributes attributes; -@property (nonatomic) CGSize constrainedSize; +- (instancetype)initWithAttributes:(ASTextKitAttributes)attributes constrainedSize:(CGSize)constrainedSize; @end @implementation ASTextNodeRendererKey { - std::mutex _m; + ASTextKitAttributes _attributes; + CGSize _constrainedSize; +} + +- (instancetype)initWithAttributes:(ASTextKitAttributes)attributes constrainedSize:(CGSize)constrainedSize +{ + if (self = [super init]) { + _attributes = attributes; + _constrainedSize = constrainedSize; + } + return self; } - (NSUInteger)hash { - std::lock_guard _l(_m); #pragma clang diagnostic push #pragma clang diagnostic warning "-Wpadded" struct { @@ -87,13 +95,11 @@ - (BOOL)isEqual:(ASTextNodeRendererKey *)object if (self == object) { return YES; } + if (!object || ![object isKindOfClass:[self class]]) { + return NO; + } // NOTE: Skip the class check for this specialized, internal Key object. - - // Lock both objects, avoiding deadlock. - std::lock(_m, object->_m); - std::lock_guard lk1(_m, std::adopt_lock); - std::lock_guard lk2(object->_m, std::adopt_lock); return _attributes == object->_attributes && CGSizeEqualToSize(_constrainedSize, object->_constrainedSize); } @@ -121,9 +127,7 @@ - (BOOL)isEqual:(ASTextNodeRendererKey *)object { NSCache *cache = sharedRendererCache(); - ASTextNodeRendererKey *key = [[ASTextNodeRendererKey alloc] init]; - key.attributes = attributes; - key.constrainedSize = constrainedSize; + ASTextNodeRendererKey *key = [[ASTextNodeRendererKey alloc] initWithAttributes:attributes constrainedSize:constrainedSize]; ASTextKitRenderer *renderer = [cache objectForKey:key]; if (renderer == nil) { From f41df18263e2d36b6be9c11978eafb844f8058b6 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Mon, 15 Apr 2019 16:01:55 +0800 Subject: [PATCH 2/5] Remove class check for isEqual --- Source/ASTextNode.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index c48d36efa..d25bd4fbb 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -95,10 +95,9 @@ - (BOOL)isEqual:(ASTextNodeRendererKey *)object if (self == object) { return YES; } - if (!object || ![object isKindOfClass:[self class]]) { + if (!object) { return NO; } - // NOTE: Skip the class check for this specialized, internal Key object. return _attributes == object->_attributes && CGSizeEqualToSize(_constrainedSize, object->_constrainedSize); From 6211dc7a294beba2059e36f7c81ff5d766a7f25f Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Mon, 15 Apr 2019 16:57:57 +0800 Subject: [PATCH 3/5] Add const specifier to function parameter --- Source/ASTextNode.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index d25bd4fbb..5b3f70c8c 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -58,7 +58,7 @@ #pragma mark - ASTextKitRenderer @interface ASTextNodeRendererKey : NSObject -- (instancetype)initWithAttributes:(ASTextKitAttributes)attributes constrainedSize:(CGSize)constrainedSize; +- (instancetype)initWithTextKitAttributes:(const ASTextKitAttributes &)attributes constrainedSize:(const CGSize)constrainedSize; @end @implementation ASTextNodeRendererKey { @@ -66,7 +66,7 @@ @implementation ASTextNodeRendererKey { CGSize _constrainedSize; } -- (instancetype)initWithAttributes:(ASTextKitAttributes)attributes constrainedSize:(CGSize)constrainedSize +- (instancetype)initWithTextKitAttributes:(const ASTextKitAttributes &)attributes constrainedSize:(const CGSize)constrainedSize { if (self = [super init]) { _attributes = attributes; @@ -126,7 +126,7 @@ - (BOOL)isEqual:(ASTextNodeRendererKey *)object { NSCache *cache = sharedRendererCache(); - ASTextNodeRendererKey *key = [[ASTextNodeRendererKey alloc] initWithAttributes:attributes constrainedSize:constrainedSize]; + ASTextNodeRendererKey *key = [[ASTextNodeRendererKey alloc] initWithTextKitAttributes:attributes constrainedSize:constrainedSize]; ASTextKitRenderer *renderer = [cache objectForKey:key]; if (renderer == nil) { From e1703ebbd1353a25c7a8494bc8516e4f90874414 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Thu, 18 Apr 2019 16:04:11 +0800 Subject: [PATCH 4/5] Fixes typo --- Source/ASVisibilityProtocols.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ASVisibilityProtocols.h b/Source/ASVisibilityProtocols.h index 837e84826..f350a3444 100644 --- a/Source/ASVisibilityProtocols.h +++ b/Source/ASVisibilityProtocols.h @@ -38,7 +38,7 @@ AS_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visib * @discussion Represents the number of user actions necessary to reach the view controller. An increased visibility * depth indicates a higher number of user interactions for the view controller to be visible again. For example, * an onscreen navigation controller's top view controller should have a visibility depth of 0. The view controller - * one from the top should have a visibility deptch of 1 as should the root view controller in the stack (because + * one from the top should have a visibility depth of 1 as should the root view controller in the stack (because * the user can hold the back button to pop to the root view controller). * * Visibility depth is used to automatically adjust ranges on range controllers (and thus free up memory) and can From 23881ce470e41752cdaacd6a8a0d3d94ec55fc43 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Thu, 18 Apr 2019 16:20:14 +0800 Subject: [PATCH 5/5] Fixes typo --- Source/ASDisplayNode.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 458941b97..b80d6c666 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -119,7 +119,7 @@ void StubImplementationWithTwoInterfaceStates(id receiver, SEL _cmd, ASInterface * @remarks The instance value is used only if we suspect the class may be dynamic (because it overloads * +respondsToSelector: or -respondsToSelector.) In that case we use our "slow path", calling this * method on each -init and passing the instance value. While this may seem like an unlikely scenario, - * it turns our our own internal tests use a dynamic class, so it's worth capturing this edge case. + * it turns out our own internal tests use a dynamic class, so it's worth capturing this edge case. * * @return ASDisplayNode flags. */