mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-18 03:20:09 +00:00
ASDisplayNode and several subclasses had previously cleared memory-heavy objects like the backing store and text layout manager when the node's view or layer is removed from a visible heirarchy. This works great in any system that uses a "working range", where exiting the range removes the node from the hierarchy and reclaiming memory at that time is important. However, for standard UIViewController patterns (unused in Paper), this behavior causes highly undesirable thrashing (leading to visible flashes & wasteful re-rendering of content). After this change, node subclasses should implement -reclaimMemory if they need to perform any other cleanup besides backing store destruction when they leave a working range or other scenario where memory reduction is valuable. To trigger this behavior, calling code should use -recursivelyReclaimMemory. r=nadi
124 lines
4.1 KiB
Objective-C
124 lines
4.1 KiB
Objective-C
/* 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.
|
|
*/
|
|
|
|
//
|
|
// The following methods are ONLY for use by _ASDisplayLayer, _ASDisplayView, and ASDisplayNode.
|
|
// These methods must never be called or overridden by other classes.
|
|
//
|
|
|
|
#import "_ASDisplayLayer.h"
|
|
#import "_AS-objc-internal.h"
|
|
#import "ASDisplayNodeExtraIvars.h"
|
|
#import "ASDisplayNode.h"
|
|
#import "ASSentinel.h"
|
|
#import "ASThread.h"
|
|
|
|
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
|
|
|
|
@class _ASPendingState;
|
|
|
|
// Allow 2^n increments of begin disabling hierarchy notifications
|
|
#define visibilityNotificationsDisabledBits 4
|
|
|
|
#define TIME_DISPLAYNODE_OPS (DEBUG || PROFILE)
|
|
|
|
@interface ASDisplayNode () <_ASDisplayLayerDelegate>
|
|
{
|
|
@protected
|
|
ASDN::RecursiveMutex _propertyLock; // Protects access to the _view, _pendingViewState, _subnodes, _supernode, _renderingSubnodes, and other properties which are accessed from multiple threads.
|
|
|
|
ASDisplayNode * __weak _supernode;
|
|
|
|
ASSentinel *_displaySentinel;
|
|
ASSentinel *_replaceAsyncSentinel;
|
|
|
|
// This is the desired contentsScale, not the scale at which the layer's contents should be displayed
|
|
CGFloat _contentsScaleForDisplay;
|
|
|
|
CGSize _size;
|
|
CGSize _constrainedSize;
|
|
UIEdgeInsets _hitTestSlop;
|
|
NSMutableArray *_subnodes;
|
|
|
|
Class _viewClass;
|
|
Class _layerClass;
|
|
UIView *_view;
|
|
CALayer *_layer;
|
|
|
|
_ASPendingState *_pendingViewState;
|
|
|
|
struct {
|
|
unsigned implementsDisplay:1;
|
|
unsigned isSynchronous:1;
|
|
unsigned isLayerBacked:1;
|
|
unsigned sizeCalculated:1;
|
|
unsigned preventOrCancelDisplay:1;
|
|
unsigned displaysAsynchronously:1;
|
|
unsigned shouldRasterizeDescendants:1;
|
|
unsigned visibilityNotificationsDisabled:visibilityNotificationsDisabledBits;
|
|
unsigned isInEnterHierarchy:1;
|
|
unsigned isInExitHierarchy:1;
|
|
unsigned inWindow:1;
|
|
unsigned hasWillDisplayAsyncLayer:1;
|
|
unsigned hasDrawParametersForAsyncLayer:1;
|
|
unsigned hasClassDisplay:1;
|
|
} _flags;
|
|
|
|
ASDisplayNodeExtraIvars _extra;
|
|
|
|
#if TIME_DISPLAYNODE_OPS
|
|
@public
|
|
NSTimeInterval _debugTimeToCreateView;
|
|
NSTimeInterval _debugTimeToApplyPendingState;
|
|
NSTimeInterval _debugTimeToAddSubnodeViews;
|
|
NSTimeInterval _debugTimeForDidLoad;
|
|
#endif
|
|
|
|
}
|
|
|
|
// The _ASDisplayLayer backing the node, if any.
|
|
@property (nonatomic, readonly, retain) _ASDisplayLayer *asyncLayer;
|
|
|
|
// Creates a pendingViewState if one doesn't exist. Allows setting view properties on a bg thread before there is a view.
|
|
@property (atomic, retain, readonly) _ASPendingState *pendingViewState;
|
|
|
|
// Swizzle to extend the builtin functionality with custom logic
|
|
- (BOOL)__shouldLoadViewOrLayer;
|
|
- (BOOL)__shouldSize;
|
|
|
|
- (void)__layout;
|
|
- (void)__setSupernode:(ASDisplayNode *)supernode;
|
|
|
|
// The visibility state of the node. Changed before calling willAppear, willDisappear, and didDisappear.
|
|
@property (nonatomic, readwrite, assign, getter = isInWindow) BOOL inWindow;
|
|
|
|
// Private API for helper funcitons / unit tests. Use ASDisplayNodeDisableHierarchyNotifications() to control this.
|
|
- (BOOL)__visibilityNotificationsDisabled;
|
|
- (void)__incrementVisibilityNotificationsDisabled;
|
|
- (void)__decrementVisibilityNotificationsDisabled;
|
|
|
|
// Call willEnterHierarchy if necessary and set inWindow = YES if visibility notifications are enabled on all of its parents
|
|
- (void)__enterHierarchy;
|
|
// Call didExitHierarchy if necessary and set inWindow = NO if visibility notifications are enabled on all of its parents
|
|
- (void)__exitHierarchy;
|
|
|
|
// Returns the ancestor node that rasterizes descendants, or nil if none.
|
|
- (ASDisplayNode *)__rasterizedContainerNode;
|
|
|
|
@property (nonatomic, assign) CGFloat contentsScaleForDisplay;
|
|
|
|
@end
|
|
|
|
@interface UIView (ASDisplayNodeInternal)
|
|
@property (nonatomic, assign, readwrite) ASDisplayNode *asyncdisplaykit_node;
|
|
@end
|
|
|
|
@interface CALayer (ASDisplayNodeInternal)
|
|
@property (nonatomic, assign, readwrite) ASDisplayNode *asyncdisplaykit_node;
|
|
@end
|