mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-15 18:59:54 +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)
|
||||
- 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)
|
||||
- Optimize text stack by removing unneeded copying. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
|
||||
## 2.7
|
||||
- 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();
|
||||
|
||||
ASTextContainer *container = [_textContainer copy];
|
||||
NSAttributedString *attributedText = self.attributedText;
|
||||
container.size = constrainedSize;
|
||||
ASTextContainer *container;
|
||||
if (!CGSizeEqualToSize(container.size, constrainedSize)) {
|
||||
container = [_textContainer copy];
|
||||
container.size = constrainedSize;
|
||||
[container makeImmutable];
|
||||
} else {
|
||||
container = _textContainer;
|
||||
}
|
||||
[self _ensureTruncationText];
|
||||
|
||||
NSMutableAttributedString *mutableText = [attributedText mutableCopy];
|
||||
NSMutableAttributedString *mutableText = [_attributedText mutableCopy];
|
||||
[self prepareAttributedString:mutableText];
|
||||
ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:container text:mutableText];
|
||||
|
||||
@ -365,9 +370,12 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
{
|
||||
ASLockScopeSelf();
|
||||
[self _ensureTruncationText];
|
||||
|
||||
// Unlike layout, here we must copy the container since drawing is asynchronous.
|
||||
ASTextContainer *copiedContainer = [_textContainer copy];
|
||||
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];
|
||||
|
||||
|
||||
@ -67,6 +67,9 @@ AS_EXTERN const CGSize ASTextContainerMaxSize;
|
||||
/// Creates a container with the specified path. @param path The path.
|
||||
+ (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)
|
||||
@property CGSize size;
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASTextLayout.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASAssert.h>
|
||||
#import <AsyncDisplayKit/ASConfigurationInternal.h>
|
||||
#import <AsyncDisplayKit/ASTextUtilities.h>
|
||||
#import <AsyncDisplayKit/ASTextAttribute.h>
|
||||
@ -134,26 +135,36 @@ static CGColorRef ASTextGetCGColor(CGColorRef color) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
ASTextContainer *one = [self.class new];
|
||||
- (id)copyForced:(BOOL)forceCopy
|
||||
{
|
||||
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->_insets = _insets;
|
||||
one->_path = _path;
|
||||
one->_exclusionPaths = _exclusionPaths.copy;
|
||||
one->_exclusionPaths = [_exclusionPaths copy];
|
||||
one->_pathFillEvenOdd = _pathFillEvenOdd;
|
||||
one->_pathLineWidth = _pathLineWidth;
|
||||
one->_verticalForm = _verticalForm;
|
||||
one->_maximumNumberOfRows = _maximumNumberOfRows;
|
||||
one->_truncationType = _truncationType;
|
||||
one->_truncationToken = _truncationToken.copy;
|
||||
one->_truncationToken = [_truncationToken copy];
|
||||
one->_linePositionModifier = [(NSObject *)_linePositionModifier copy];
|
||||
dispatch_semaphore_signal(_lock);
|
||||
return one;
|
||||
}
|
||||
|
||||
- (id)mutableCopyWithZone:(nullable NSZone *)zone {
|
||||
return [self copyWithZone:zone];
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
return [self copyForced:NO];
|
||||
}
|
||||
|
||||
- (id)mutableCopyWithZone:(NSZone *)zone {
|
||||
return [self copyForced:YES];
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
@ -189,18 +200,25 @@ static CGColorRef ASTextGetCGColor(CGColorRef color) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)makeImmutable
|
||||
{
|
||||
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
|
||||
_readonly = YES;
|
||||
dispatch_semaphore_signal(_lock);
|
||||
}
|
||||
|
||||
#define Getter(...) \
|
||||
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
|
||||
__VA_ARGS__; \
|
||||
dispatch_semaphore_signal(_lock);
|
||||
|
||||
#define Setter(...) \
|
||||
if (_readonly) { \
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException \
|
||||
reason:@"Cannot change the property of the 'container' in 'ASTextLayout'." userInfo:nil]; \
|
||||
return; \
|
||||
} \
|
||||
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
|
||||
if (__builtin_expect(_readonly, NO)) { \
|
||||
ASDisplayNodeFailAssert(@"Attempt to modify immutable text container."); \
|
||||
dispatch_semaphore_signal(_lock); \
|
||||
return; \
|
||||
} \
|
||||
__VA_ARGS__; \
|
||||
dispatch_semaphore_signal(_lock);
|
||||
|
||||
@ -407,11 +425,10 @@ dispatch_semaphore_signal(_lock);
|
||||
if (lineRowsIndex) free(lineRowsIndex); \
|
||||
return nil; }
|
||||
|
||||
text = text.mutableCopy;
|
||||
container = container.copy;
|
||||
container = [container copy];
|
||||
if (!text || !container) return nil;
|
||||
if (range.location + range.length > text.length) return nil;
|
||||
container->_readonly = YES;
|
||||
[container makeImmutable];
|
||||
maximumNumberOfRows = container.maximumNumberOfRows;
|
||||
|
||||
// It may use larger constraint size when create CTFrame with
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user