mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-16 19:30:29 +00:00
Reduce copying in ASTextNode2 stack (#1065)
* Remove copying in text stack, make text container have an optional immutable mode * Changelog * Comment * Update CHANGELOG.md * Use new name * Import header
This commit is contained in:
parent
2bb216b02e
commit
03e6ce0916
@ -31,6 +31,7 @@
|
|||||||
- Optimize display node accessibility by not creating attributed & non-attributed copies of hint, label, and value. [Adlai Holler](https://github.com/Adlai-Holler)
|
- Optimize display node accessibility by not creating attributed & non-attributed copies of hint, label, and value. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||||
- Add an experimental feature that reuses CTFramesetter objects in ASTextNode2 to improve performance. [Adlai Holler](https://github.com/Adlai-Holler)
|
- Add an experimental feature that reuses CTFramesetter objects in ASTextNode2 to improve performance. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||||
- Add NS_DESIGNATED_INITIALIZER to ASViewController initWithNode: [Michael Schneider](https://github.com/maicki) [#1054](https://github.com/TextureGroup/Texture/pull/1054)
|
- Add NS_DESIGNATED_INITIALIZER to ASViewController initWithNode: [Michael Schneider](https://github.com/maicki) [#1054](https://github.com/TextureGroup/Texture/pull/1054)
|
||||||
|
- Optimize text stack by removing unneeded copying. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||||
|
|
||||||
## 2.7
|
## 2.7
|
||||||
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)
|
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)
|
||||||
|
|||||||
@ -236,12 +236,17 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
|
|
||||||
ASLockScopeSelf();
|
ASLockScopeSelf();
|
||||||
|
|
||||||
ASTextContainer *container = [_textContainer copy];
|
ASTextContainer *container;
|
||||||
NSAttributedString *attributedText = self.attributedText;
|
if (!CGSizeEqualToSize(container.size, constrainedSize)) {
|
||||||
|
container = [_textContainer copy];
|
||||||
container.size = constrainedSize;
|
container.size = constrainedSize;
|
||||||
|
[container makeImmutable];
|
||||||
|
} else {
|
||||||
|
container = _textContainer;
|
||||||
|
}
|
||||||
[self _ensureTruncationText];
|
[self _ensureTruncationText];
|
||||||
|
|
||||||
NSMutableAttributedString *mutableText = [attributedText mutableCopy];
|
NSMutableAttributedString *mutableText = [_attributedText mutableCopy];
|
||||||
[self prepareAttributedString:mutableText];
|
[self prepareAttributedString:mutableText];
|
||||||
ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:container text:mutableText];
|
ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:container text:mutableText];
|
||||||
|
|
||||||
@ -365,9 +370,12 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
|||||||
{
|
{
|
||||||
ASLockScopeSelf();
|
ASLockScopeSelf();
|
||||||
[self _ensureTruncationText];
|
[self _ensureTruncationText];
|
||||||
|
|
||||||
|
// Unlike layout, here we must copy the container since drawing is asynchronous.
|
||||||
ASTextContainer *copiedContainer = [_textContainer copy];
|
ASTextContainer *copiedContainer = [_textContainer copy];
|
||||||
copiedContainer.size = self.bounds.size;
|
copiedContainer.size = self.bounds.size;
|
||||||
NSMutableAttributedString *mutableText = [self.attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init];
|
[copiedContainer makeImmutable];
|
||||||
|
NSMutableAttributedString *mutableText = [_attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init];
|
||||||
|
|
||||||
[self prepareAttributedString:mutableText];
|
[self prepareAttributedString:mutableText];
|
||||||
|
|
||||||
|
|||||||
@ -67,6 +67,9 @@ AS_EXTERN const CGSize ASTextContainerMaxSize;
|
|||||||
/// Creates a container with the specified path. @param path The path.
|
/// Creates a container with the specified path. @param path The path.
|
||||||
+ (instancetype)containerWithPath:(nullable UIBezierPath *)path NS_RETURNS_RETAINED;
|
+ (instancetype)containerWithPath:(nullable UIBezierPath *)path NS_RETURNS_RETAINED;
|
||||||
|
|
||||||
|
/// Mark this immutable, so you get free copies going forward.
|
||||||
|
- (void)makeImmutable;
|
||||||
|
|
||||||
/// The constrained size. (if the size is larger than ASTextContainerMaxSize, it will be clipped)
|
/// The constrained size. (if the size is larger than ASTextContainerMaxSize, it will be clipped)
|
||||||
@property CGSize size;
|
@property CGSize size;
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#import <AsyncDisplayKit/ASTextLayout.h>
|
#import <AsyncDisplayKit/ASTextLayout.h>
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/ASAssert.h>
|
||||||
#import <AsyncDisplayKit/ASConfigurationInternal.h>
|
#import <AsyncDisplayKit/ASConfigurationInternal.h>
|
||||||
#import <AsyncDisplayKit/ASTextUtilities.h>
|
#import <AsyncDisplayKit/ASTextUtilities.h>
|
||||||
#import <AsyncDisplayKit/ASTextAttribute.h>
|
#import <AsyncDisplayKit/ASTextAttribute.h>
|
||||||
@ -134,26 +135,36 @@ static CGColorRef ASTextGetCGColor(CGColorRef color) {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)copyWithZone:(NSZone *)zone {
|
- (id)copyForced:(BOOL)forceCopy
|
||||||
ASTextContainer *one = [self.class new];
|
{
|
||||||
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
|
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
|
||||||
|
if (_readonly && !forceCopy) {
|
||||||
|
dispatch_semaphore_signal(_lock);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTextContainer *one = [self.class new];
|
||||||
one->_size = _size;
|
one->_size = _size;
|
||||||
one->_insets = _insets;
|
one->_insets = _insets;
|
||||||
one->_path = _path;
|
one->_path = _path;
|
||||||
one->_exclusionPaths = _exclusionPaths.copy;
|
one->_exclusionPaths = [_exclusionPaths copy];
|
||||||
one->_pathFillEvenOdd = _pathFillEvenOdd;
|
one->_pathFillEvenOdd = _pathFillEvenOdd;
|
||||||
one->_pathLineWidth = _pathLineWidth;
|
one->_pathLineWidth = _pathLineWidth;
|
||||||
one->_verticalForm = _verticalForm;
|
one->_verticalForm = _verticalForm;
|
||||||
one->_maximumNumberOfRows = _maximumNumberOfRows;
|
one->_maximumNumberOfRows = _maximumNumberOfRows;
|
||||||
one->_truncationType = _truncationType;
|
one->_truncationType = _truncationType;
|
||||||
one->_truncationToken = _truncationToken.copy;
|
one->_truncationToken = [_truncationToken copy];
|
||||||
one->_linePositionModifier = [(NSObject *)_linePositionModifier copy];
|
one->_linePositionModifier = [(NSObject *)_linePositionModifier copy];
|
||||||
dispatch_semaphore_signal(_lock);
|
dispatch_semaphore_signal(_lock);
|
||||||
return one;
|
return one;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)mutableCopyWithZone:(nullable NSZone *)zone {
|
- (id)copyWithZone:(NSZone *)zone {
|
||||||
return [self copyWithZone:zone];
|
return [self copyForced:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)mutableCopyWithZone:(NSZone *)zone {
|
||||||
|
return [self copyForced:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||||
@ -189,18 +200,25 @@ static CGColorRef ASTextGetCGColor(CGColorRef color) {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)makeImmutable
|
||||||
|
{
|
||||||
|
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
|
||||||
|
_readonly = YES;
|
||||||
|
dispatch_semaphore_signal(_lock);
|
||||||
|
}
|
||||||
|
|
||||||
#define Getter(...) \
|
#define Getter(...) \
|
||||||
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
|
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
|
||||||
__VA_ARGS__; \
|
__VA_ARGS__; \
|
||||||
dispatch_semaphore_signal(_lock);
|
dispatch_semaphore_signal(_lock);
|
||||||
|
|
||||||
#define Setter(...) \
|
#define Setter(...) \
|
||||||
if (_readonly) { \
|
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
|
||||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException \
|
if (__builtin_expect(_readonly, NO)) { \
|
||||||
reason:@"Cannot change the property of the 'container' in 'ASTextLayout'." userInfo:nil]; \
|
ASDisplayNodeFailAssert(@"Attempt to modify immutable text container."); \
|
||||||
|
dispatch_semaphore_signal(_lock); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
|
|
||||||
__VA_ARGS__; \
|
__VA_ARGS__; \
|
||||||
dispatch_semaphore_signal(_lock);
|
dispatch_semaphore_signal(_lock);
|
||||||
|
|
||||||
@ -407,11 +425,10 @@ dispatch_semaphore_signal(_lock);
|
|||||||
if (lineRowsIndex) free(lineRowsIndex); \
|
if (lineRowsIndex) free(lineRowsIndex); \
|
||||||
return nil; }
|
return nil; }
|
||||||
|
|
||||||
text = text.mutableCopy;
|
container = [container copy];
|
||||||
container = container.copy;
|
|
||||||
if (!text || !container) return nil;
|
if (!text || !container) return nil;
|
||||||
if (range.location + range.length > text.length) return nil;
|
if (range.location + range.length > text.length) return nil;
|
||||||
container->_readonly = YES;
|
[container makeImmutable];
|
||||||
maximumNumberOfRows = container.maximumNumberOfRows;
|
maximumNumberOfRows = container.maximumNumberOfRows;
|
||||||
|
|
||||||
// It may use larger constraint size when create CTFrame with
|
// It may use larger constraint size when create CTFrame with
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user