mirror of
https://github.com/TextureGroup/Texture.git
synced 2026-04-07 19:17:39 +00:00
* Revert "Revert "[ASLayoutSpec] Use childrenMap directly to prevent creating an NSArray within ASDK (#1937)""
This reverts commit 735b4ebd08.
* Fix crash and add exception for mutating while using fast enumeration of ASLayoutSpec children
NSFastEnumeration is potentially quite dangerous in the wrong hands. In particular, it does not provide a safe mechanism for you to return temporary objects directly, and it does not provide any guarantee that you will be called when the enumeration has completed; therefore if we generate temporaries and store them in an instance variable, we will not necessarily be able to clean them up! This means fast enumeration methods should never be called within an autorelease pool or the autorelease pool be drained within the fast enumeration loop.
The reason is we store references to objects in the stackBuf struct by casting the child pointer to __autoreleasing id. If we pop the autorelease pool between calls to -countByEnumeratingWithState:objects:count:, it will die in a messy explosion of pointer dereferences and EXC_BAD_ACCESS.
* Add tests for ASDisplayNode and ASLayoutSpec fast enumeration
95 lines
2.9 KiB
Plaintext
95 lines
2.9 KiB
Plaintext
//
|
|
// ASStaticLayoutSpec.mm
|
|
// AsyncDisplayKit
|
|
//
|
|
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under the BSD-style license found in the
|
|
// LICENSE file in the root directory of this source tree. An additional grant
|
|
// of patent rights can be found in the PATENTS file in the same directory.
|
|
//
|
|
|
|
#import "ASStaticLayoutSpec.h"
|
|
|
|
#import "ASLayoutSpec+Private.h"
|
|
#import "ASLayoutSpecUtilities.h"
|
|
#import "ASLayout.h"
|
|
|
|
@implementation ASStaticLayoutSpec
|
|
|
|
+ (instancetype)staticLayoutSpecWithChildren:(NSArray *)children
|
|
{
|
|
return [[self alloc] initWithChildren:children];
|
|
}
|
|
|
|
- (instancetype)init
|
|
{
|
|
return [self initWithChildren:@[]];
|
|
}
|
|
|
|
- (instancetype)initWithChildren:(NSArray *)children
|
|
{
|
|
if (!(self = [super init])) {
|
|
return nil;
|
|
}
|
|
self.children = children;
|
|
return self;
|
|
}
|
|
|
|
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
|
{
|
|
CGSize maxConstrainedSize = CGSizeMake(constrainedSize.max.width, constrainedSize.max.height);
|
|
|
|
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:self.childrenMap.size()];
|
|
for (id<ASLayoutable> child in self) {
|
|
CGPoint layoutPosition = child.layoutPosition;
|
|
CGSize autoMaxSize = CGSizeMake(maxConstrainedSize.width - layoutPosition.x,
|
|
maxConstrainedSize.height - layoutPosition.y);
|
|
|
|
ASRelativeSizeRange childSizeRange = child.sizeRange;
|
|
BOOL childIsUnconstrained = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, childSizeRange);
|
|
ASSizeRange childConstraint = childIsUnconstrained ? ASSizeRangeMake({0, 0}, autoMaxSize)
|
|
: ASRelativeSizeRangeResolve(childSizeRange, maxConstrainedSize);
|
|
|
|
ASLayout *sublayout = [child measureWithSizeRange:childConstraint];
|
|
sublayout.position = layoutPosition;
|
|
[sublayouts addObject:sublayout];
|
|
}
|
|
|
|
CGSize size = CGSizeMake(constrainedSize.min.width, constrainedSize.min.height);
|
|
|
|
for (ASLayout *sublayout in sublayouts) {
|
|
CGPoint sublayoutPosition = sublayout.position;
|
|
CGSize sublayoutSize = sublayout.size;
|
|
|
|
size.width = MAX(size.width, sublayoutPosition.x + sublayoutSize.width);
|
|
size.height = MAX(size.height, sublayoutPosition.y + sublayoutSize.height);
|
|
}
|
|
|
|
return [ASLayout layoutWithLayoutableObject:self
|
|
constrainedSizeRange:constrainedSize
|
|
size:ASSizeRangeClamp(constrainedSize, size)
|
|
sublayouts:sublayouts];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ASStaticLayoutSpec (ASEnvironment)
|
|
|
|
- (BOOL)supportsUpwardPropagation
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ASStaticLayoutSpec (Debugging)
|
|
|
|
#pragma mark - ASLayoutableAsciiArtProtocol
|
|
|
|
- (NSString *)debugBoxString
|
|
{
|
|
return [ASLayoutSpec asciiArtStringForChildren:self.children parentName:[self asciiArtName]];
|
|
}
|
|
|
|
@end
|