mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
2611 rename fetch data (#2689)
* Replace fetch data with preload terminology - Deprecate `-fetchData` and `-clearFetchedData` in favor of `-preload` and `-clearPreloadedData` - Move `-setNeedsPreload`, `-recursivelyPreload` and `-recursivelyClearPreloadedData` to ASDisplayNode+FrameworkPrivate.h - Update internal implementation, comments and tests * Folllow up on #2642: - Remove -preload and -clearPreloadedData in favor of -didEnterPreloadState and -didExitPreloadState. - -didEnterPreloadState and -didExitPreloadState call the deprecated -fetchData and -clearFetchedData methods if they are overriden. * Missed one in a test * Get rid of behavior change for now. * Revert more behavior changes, fix tests. * Don't need these anymore.
This commit is contained in:
committed by
Hannah Troisi
parent
c7ea15a5e4
commit
ba2268ac99
@@ -167,10 +167,10 @@
|
|||||||
[self.rangeController clearContents];
|
[self.rangeController clearContents];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)didExitPreloadState
|
||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super didExitPreloadState];
|
||||||
[self.rangeController clearFetchedData];
|
[self.rangeController clearPreloadedData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState
|
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState
|
||||||
|
|||||||
@@ -1681,18 +1681,6 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
|||||||
_nextLayoutInvalidationStyle = invalidationStyle;
|
_nextLayoutInvalidationStyle = invalidationStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Memory Management
|
|
||||||
|
|
||||||
- (void)clearContents
|
|
||||||
{
|
|
||||||
[_rangeController clearContents];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)clearFetchedData
|
|
||||||
{
|
|
||||||
[_rangeController clearFetchedData];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - _ASDisplayView behavior substitutions
|
#pragma mark - _ASDisplayView behavior substitutions
|
||||||
// Need these to drive interfaceState so we know when we are visible, if not nested in another range-managing element.
|
// Need these to drive interfaceState so we know when we are visible, if not nested in another range-managing element.
|
||||||
// Because our superclass is a true UIKit class, we cannot also subclass _ASDisplayView.
|
// Because our superclass is a true UIKit class, we cannot also subclass _ASDisplayView.
|
||||||
|
|||||||
@@ -115,4 +115,21 @@ ASLayoutElementStyleForwardingDeclaration
|
|||||||
*/
|
*/
|
||||||
@property (nonatomic, assign) BOOL usesImplicitHierarchyManagement ASDISPLAYNODE_DEPRECATED_MSG("Set .automaticallyManagesSubnodes instead.");
|
@property (nonatomic, assign) BOOL usesImplicitHierarchyManagement ASDISPLAYNODE_DEPRECATED_MSG("Set .automaticallyManagesSubnodes instead.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Indicates that the node should fetch any external data, such as images.
|
||||||
|
*
|
||||||
|
* @discussion Subclasses may override this method to be notified when they should begin to preload. Fetching
|
||||||
|
* should be done asynchronously. The node is also responsible for managing the memory of any data.
|
||||||
|
* The data may be remote and accessed via the network, but could also be a local database query.
|
||||||
|
*/
|
||||||
|
- (void)fetchData ASDISPLAYNODE_REQUIRES_SUPER ASDISPLAYNODE_DEPRECATED_MSG("Use -didEnterPreloadState instead.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an opportunity to clear any fetched data (e.g. remote / network or database-queried) on the current node.
|
||||||
|
*
|
||||||
|
* @discussion This will not clear data recursively for all subnodes. Either call -recursivelyClearPreloadedData or
|
||||||
|
* selectively clear fetched data.
|
||||||
|
*/
|
||||||
|
- (void)clearFetchedData ASDISPLAYNODE_REQUIRES_SUPER ASDISPLAYNODE_DEPRECATED_MSG("Use -didExitPreloadState instead.");
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -323,23 +323,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
*/
|
*/
|
||||||
@property (nonatomic, readonly, assign, getter=isInHierarchy) BOOL inHierarchy;
|
@property (nonatomic, readonly, assign, getter=isInHierarchy) BOOL inHierarchy;
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract Indicates that the node should fetch any external data, such as images.
|
|
||||||
*
|
|
||||||
* @discussion Subclasses may override this method to be notified when they should begin to fetch data. Fetching
|
|
||||||
* should be done asynchronously. The node is also responsible for managing the memory of any data.
|
|
||||||
* The data may be remote and accessed via the network, but could also be a local database query.
|
|
||||||
*/
|
|
||||||
- (void)fetchData ASDISPLAYNODE_REQUIRES_SUPER;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides an opportunity to clear any fetched data (e.g. remote / network or database-queried) on the current node.
|
|
||||||
*
|
|
||||||
* @discussion This will not clear data recursively for all subnodes. Either call -recursivelyClearFetchedData or
|
|
||||||
* selectively clear fetched data.
|
|
||||||
*/
|
|
||||||
- (void)clearFetchedData ASDISPLAYNODE_REQUIRES_SUPER;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an opportunity to clear backing store and other memory-intensive intermediates, such as text layout managers
|
* Provides an opportunity to clear backing store and other memory-intensive intermediates, such as text layout managers
|
||||||
* on the current node.
|
* on the current node.
|
||||||
|
|||||||
@@ -478,31 +478,6 @@ extern NSInteger const ASDefaultDrawingPriority;
|
|||||||
*/
|
*/
|
||||||
- (void)recursivelyClearContents;
|
- (void)recursivelyClearContents;
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract Calls -clearFetchedData on the receiver and its subnode hierarchy.
|
|
||||||
*
|
|
||||||
* @discussion Clears any memory-intensive fetched content.
|
|
||||||
* This method is used to notify the node that it should purge any content that is both expensive to fetch and to
|
|
||||||
* retain in memory.
|
|
||||||
*
|
|
||||||
* @see [ASDisplayNode(Subclassing) clearFetchedData] and [ASDisplayNode(Subclassing) fetchData]
|
|
||||||
*/
|
|
||||||
- (void)recursivelyClearFetchedData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract Calls -fetchData on the receiver and its subnode hierarchy.
|
|
||||||
*
|
|
||||||
* @discussion Fetches content from remote sources for the current node and all subnodes.
|
|
||||||
*
|
|
||||||
* @see [ASDisplayNode(Subclassing) fetchData] and [ASDisplayNode(Subclassing) clearFetchedData]
|
|
||||||
*/
|
|
||||||
- (void)recursivelyFetchData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract Triggers a recursive call to fetchData when the node has an interfaceState of ASInterfaceStatePreload
|
|
||||||
*/
|
|
||||||
- (void)setNeedsDataFetch;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Toggle displaying a placeholder over the node that covers content until the node and all subnodes are
|
* @abstract Toggle displaying a placeholder over the node that covers content until the node and all subnodes are
|
||||||
* displayed.
|
* displayed.
|
||||||
|
|||||||
@@ -184,6 +184,12 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(layoutSpecThatFits:))) {
|
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(layoutSpecThatFits:))) {
|
||||||
overrides |= ASDisplayNodeMethodOverrideLayoutSpecThatFits;
|
overrides |= ASDisplayNodeMethodOverrideLayoutSpecThatFits;
|
||||||
}
|
}
|
||||||
|
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(fetchData))) {
|
||||||
|
overrides |= ASDisplayNodeMethodOverrideFetchData;
|
||||||
|
}
|
||||||
|
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(clearFetchedData))) {
|
||||||
|
overrides |= ASDisplayNodeMethodOverrideClearFetchedData;
|
||||||
|
}
|
||||||
|
|
||||||
return overrides;
|
return overrides;
|
||||||
}
|
}
|
||||||
@@ -211,7 +217,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(layoutThatFits:)), @"Subclass %@ must not override layoutThatFits: method. Instead overwrite calculateLayoutThatFits:.", classString);
|
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(layoutThatFits:)), @"Subclass %@ must not override layoutThatFits: method. Instead overwrite calculateLayoutThatFits:.", classString);
|
||||||
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(layoutThatFits:parentSize:)), @"Subclass %@ must not override layoutThatFits:parentSize method. Instead overwrite calculateLayoutThatFits:.", classString);
|
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(layoutThatFits:parentSize:)), @"Subclass %@ must not override layoutThatFits:parentSize method. Instead overwrite calculateLayoutThatFits:.", classString);
|
||||||
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyClearContents)), @"Subclass %@ must not override recursivelyClearContents method.", classString);
|
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyClearContents)), @"Subclass %@ must not override recursivelyClearContents method.", classString);
|
||||||
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyClearFetchedData)), @"Subclass %@ must not override recursivelyClearFetchedData method.", classString);
|
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyClearPreloadedData)), @"Subclass %@ must not override recursivelyClearFetchedData method.", classString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Below we are pre-calculating values per-class and dynamically adding a method (_staticInitialize) to populate these values
|
// Below we are pre-calculating values per-class and dynamically adding a method (_staticInitialize) to populate these values
|
||||||
@@ -2930,34 +2936,24 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
- (void)setNeedsPreload
|
||||||
{
|
|
||||||
// subclass override
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setNeedsDataFetch
|
|
||||||
{
|
{
|
||||||
if (self.isInPreloadState) {
|
if (self.isInPreloadState) {
|
||||||
[self recursivelyFetchData];
|
[self recursivelyPreload];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)recursivelyFetchData
|
- (void)recursivelyPreload
|
||||||
{
|
{
|
||||||
ASDisplayNodePerformBlockOnEveryNode(nil, self, YES, ^(ASDisplayNode * _Nonnull node) {
|
ASDisplayNodePerformBlockOnEveryNode(nil, self, YES, ^(ASDisplayNode * _Nonnull node) {
|
||||||
[node fetchData];
|
[node didEnterPreloadState];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)recursivelyClearPreloadedData
|
||||||
{
|
|
||||||
// subclass override
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)recursivelyClearFetchedData
|
|
||||||
{
|
{
|
||||||
ASDisplayNodePerformBlockOnEveryNode(nil, self, YES, ^(ASDisplayNode * _Nonnull node) {
|
ASDisplayNodePerformBlockOnEveryNode(nil, self, YES, ^(ASDisplayNode * _Nonnull node) {
|
||||||
[node clearFetchedData];
|
[node didExitPreloadState];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2983,13 +2979,23 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
|
|
||||||
- (void)didEnterPreloadState
|
- (void)didEnterPreloadState
|
||||||
{
|
{
|
||||||
|
if (_methodOverrides & ASDisplayNodeMethodOverrideFetchData) {
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
[self fetchData];
|
[self fetchData];
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didExitPreloadState
|
- (void)didExitPreloadState
|
||||||
{
|
{
|
||||||
|
if (_methodOverrides & ASDisplayNodeMethodOverrideClearFetchedData) {
|
||||||
if ([self supportsRangeManagedInterfaceState]) {
|
if ([self supportsRangeManagedInterfaceState]) {
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
[self clearFetchedData];
|
[self clearFetchedData];
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3047,7 +3053,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
// Trigger asynchronous measurement if it is not already cached or being calculated.
|
// Trigger asynchronous measurement if it is not already cached or being calculated.
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the FetchData and Display ranges, we don't want to call -clear* if not being managed by a range controller.
|
// For the Preload and Display ranges, we don't want to call -clear* if not being managed by a range controller.
|
||||||
// Otherwise we get flashing behavior from normal UIKit manipulations like navigation controller push / pop.
|
// Otherwise we get flashing behavior from normal UIKit manipulations like navigation controller push / pop.
|
||||||
// Still, the interfaceState should be updated to the current state of the node; just don't act on the transition.
|
// Still, the interfaceState should be updated to the current state of the node; just don't act on the transition.
|
||||||
|
|
||||||
@@ -3946,6 +3952,16 @@ ASLayoutElementStyleForwarding
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)fetchData
|
||||||
|
{
|
||||||
|
// subclass override
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)clearFetchedData
|
||||||
|
{
|
||||||
|
// subclass override
|
||||||
|
}
|
||||||
|
|
||||||
- (void)cancelLayoutTransitionsInProgress
|
- (void)cancelLayoutTransitionsInProgress
|
||||||
{
|
{
|
||||||
[self cancelLayoutTransition];
|
[self cancelLayoutTransition];
|
||||||
|
|||||||
@@ -72,9 +72,9 @@
|
|||||||
[super setLayerBacked:layerBacked];
|
[super setLayerBacked:layerBacked];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
- (void)didEnterPreloadState
|
||||||
{
|
{
|
||||||
[super fetchData];
|
[super didEnterPreloadState];
|
||||||
ASPerformBlockOnMainThread(^{
|
ASPerformBlockOnMainThread(^{
|
||||||
if (self.isLiveMap) {
|
if (self.isLiveMap) {
|
||||||
[self addLiveMap];
|
[self addLiveMap];
|
||||||
@@ -84,9 +84,9 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)didExitPreloadState
|
||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super didExitPreloadState];
|
||||||
ASPerformBlockOnMainThread(^{
|
ASPerformBlockOnMainThread(^{
|
||||||
if (self.isLiveMap) {
|
if (self.isLiveMap) {
|
||||||
[self removeLiveMap];
|
[self removeLiveMap];
|
||||||
|
|||||||
@@ -216,12 +216,12 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
[super clearContents]; // This actually clears the contents, so we need to do this first for our displayedImageIdentifier to be meaningful.
|
[super clearContents]; // This actually clears the contents, so we need to do this first for our displayedImageIdentifier to be meaningful.
|
||||||
[self _setDisplayedImageIdentifier:nil withImage:nil];
|
[self _setDisplayedImageIdentifier:nil withImage:nil];
|
||||||
|
|
||||||
// NOTE: We intentionally do not cancel image downloads until `clearFetchedData`.
|
// NOTE: We intentionally do not cancel image downloads until `clearPreloadedData`.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)didExitPreloadState
|
||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super didExitPreloadState];
|
||||||
|
|
||||||
[_phImageRequestOperation cancel];
|
[_phImageRequestOperation cancel];
|
||||||
|
|
||||||
@@ -236,9 +236,9 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
self.image = nil;
|
self.image = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
- (void)didEnterPreloadState
|
||||||
{
|
{
|
||||||
[super fetchData];
|
[super didEnterPreloadState];
|
||||||
|
|
||||||
[self _loadImageIdentifiers];
|
[self _loadImageIdentifiers];
|
||||||
}
|
}
|
||||||
@@ -281,7 +281,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
{
|
{
|
||||||
[super displayWillStart];
|
[super displayWillStart];
|
||||||
|
|
||||||
[self fetchData];
|
[self didEnterPreloadState];
|
||||||
|
|
||||||
if (_downloaderImplementsSetPriority) {
|
if (_downloaderImplementsSetPriority) {
|
||||||
{
|
{
|
||||||
@@ -396,7 +396,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
_imageIdentifiers = [[NSArray alloc] initWithArray:imageIdentifiers copyItems:YES];
|
_imageIdentifiers = [[NSArray alloc] initWithArray:imageIdentifiers copyItems:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self setNeedsDataFetch];
|
[self setNeedsPreload];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reloadImageIdentifierSources
|
- (void)reloadImageIdentifierSources
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[self setNeedsDataFetch];
|
[self setNeedsPreload];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURL *)URL
|
- (NSURL *)URL
|
||||||
@@ -265,8 +265,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Consider removing this; it predates ASInterfaceState, which now ensures that even non-range-managed nodes get a -fetchData call.
|
// TODO: Consider removing this; it predates ASInterfaceState, which now ensures that even non-range-managed nodes get a -preload call.
|
||||||
[self fetchData];
|
[self didEnterPreloadState];
|
||||||
|
|
||||||
if (self.image == nil && _downloaderFlags.downloaderImplementsSetPriority) {
|
if (self.image == nil && _downloaderFlags.downloaderImplementsSetPriority) {
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
@@ -306,9 +306,9 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
|||||||
[self _updateProgressImageBlockOnDownloaderIfNeeded];
|
[self _updateProgressImageBlockOnDownloaderIfNeeded];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)didExitPreloadState
|
||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super didExitPreloadState];
|
||||||
|
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
@@ -321,9 +321,9 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
- (void)didEnterPreloadState
|
||||||
{
|
{
|
||||||
[super fetchData];
|
[super didEnterPreloadState];
|
||||||
|
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
|
|||||||
@@ -136,10 +136,10 @@
|
|||||||
[self.rangeController clearContents];
|
[self.rangeController clearContents];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)didExitPreloadState
|
||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super didExitPreloadState];
|
||||||
[self.rangeController clearFetchedData];
|
[self.rangeController clearPreloadedData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState
|
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState
|
||||||
|
|||||||
@@ -1646,18 +1646,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
[super endUpdates];
|
[super endUpdates];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Memory Management
|
|
||||||
|
|
||||||
- (void)clearContents
|
|
||||||
{
|
|
||||||
[_rangeController clearContents];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)clearFetchedData
|
|
||||||
{
|
|
||||||
[_rangeController clearFetchedData];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Helper Methods
|
#pragma mark - Helper Methods
|
||||||
|
|
||||||
// Note: This is called every layout, and so it is very performance sensitive.
|
// Note: This is called every layout, and so it is very performance sensitive.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
#import "ASDisplayNodeInternal.h"
|
#import "ASDisplayNodeInternal.h"
|
||||||
#import "ASDisplayNode+Subclasses.h"
|
#import "ASDisplayNode+Subclasses.h"
|
||||||
|
#import "ASDisplayNode+FrameworkPrivate.h"
|
||||||
#import "ASVideoNode.h"
|
#import "ASVideoNode.h"
|
||||||
#import "ASEqualityHelpers.h"
|
#import "ASEqualityHelpers.h"
|
||||||
#import "ASInternalHelpers.h"
|
#import "ASInternalHelpers.h"
|
||||||
@@ -365,9 +366,9 @@ static NSString * const kRate = @"rate";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
- (void)didEnterPreloadState
|
||||||
{
|
{
|
||||||
[super fetchData];
|
[super didEnterPreloadState];
|
||||||
|
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
AVAsset *asset = self.asset;
|
AVAsset *asset = self.asset;
|
||||||
@@ -405,9 +406,9 @@ static NSString * const kRate = @"rate";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)didExitPreloadState
|
||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super didExitPreloadState];
|
||||||
|
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
@@ -505,10 +506,10 @@ static NSString * const kRate = @"rate";
|
|||||||
|
|
||||||
- (void)_setAndFetchAsset:(AVAsset *)asset url:(NSURL *)assetURL
|
- (void)_setAndFetchAsset:(AVAsset *)asset url:(NSURL *)assetURL
|
||||||
{
|
{
|
||||||
[self clearFetchedData];
|
[self didExitPreloadState];
|
||||||
_asset = asset;
|
_asset = asset;
|
||||||
_assetURL = assetURL;
|
_assetURL = assetURL;
|
||||||
[self setNeedsDataFetch];
|
[self setNeedsPreload];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setVideoComposition:(AVVideoComposition *)videoComposition
|
- (void)setVideoComposition:(AVVideoComposition *)videoComposition
|
||||||
@@ -617,7 +618,7 @@ static NSString * const kRate = @"rate";
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_player == nil) {
|
if (_player == nil) {
|
||||||
[self setNeedsDataFetch];
|
[self setNeedsPreload];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_playerNode == nil) {
|
if (_playerNode == nil) {
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ typedef void(^ASImageCacherCompletion)(id <ASImageContainerProtocol> _Nullable i
|
|||||||
completion:(ASImageCacherCompletion)completion;
|
completion:(ASImageCacherCompletion)completion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@abstract Called during clearFetchedData. Allows the cache to optionally trim items.
|
@abstract Called during clearPreloadedData. Allows the cache to optionally trim items.
|
||||||
@note Depending on your caches implementation you may *not* wish to respond to this method. It is however useful
|
@note Depending on your caches implementation you may *not* wish to respond to this method. It is however useful
|
||||||
if you have a memory and disk cache in which case you'll likely want to clear out the memory cache.
|
if you have a memory and disk cache in which case you'll likely want to clear out the memory cache.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ typedef NS_ENUM(NSUInteger, ASLayoutRangeMode) {
|
|||||||
ASLayoutRangeModeFull,
|
ASLayoutRangeModeFull,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visible Only mode is used when a range controller should set its display and fetch data regions to only the size of their bounds.
|
* Visible Only mode is used when a range controller should set its display and preload regions to only the size of their bounds.
|
||||||
* This causes all additional backing stores & fetched data to be released, while ensuring a user revisiting the view will
|
* This causes all additional backing stores & preloaded data to be released, while ensuring a user revisiting the view will
|
||||||
* still be able to see the expected content. This mode is automatically set on all ASRangeControllers when the app suspends,
|
* still be able to see the expected content. This mode is automatically set on all ASRangeControllers when the app suspends,
|
||||||
* allowing the operating system to keep the app alive longer and increase the chance it is still warm when the user returns.
|
* allowing the operating system to keep the app alive longer and increase the chance it is still warm when the user returns.
|
||||||
*/
|
*/
|
||||||
@@ -40,7 +40,7 @@ typedef NS_ENUM(NSUInteger, ASLayoutRangeMode) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Low Memory mode is used when a range controller should discard ALL graphics buffers, including for the area that would be visible
|
* Low Memory mode is used when a range controller should discard ALL graphics buffers, including for the area that would be visible
|
||||||
* the next time the user views it (bounds). The only range it preserves is Fetch Data, which is limited to the bounds, allowing
|
* the next time the user views it (bounds). The only range it preserves is Preload, which is limited to the bounds, allowing
|
||||||
* the content to be restored relatively quickly by re-decoding images (the compressed images are ~10% the size of the decoded ones,
|
* the content to be restored relatively quickly by re-decoding images (the compressed images are ~10% the size of the decoded ones,
|
||||||
* and text is a tiny fraction of its rendered size).
|
* and text is a tiny fraction of its rendered size).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
// These methods call the corresponding method on each node, visiting each one that
|
// These methods call the corresponding method on each node, visiting each one that
|
||||||
// the range controller has set a non-default interface state on.
|
// the range controller has set a non-default interface state on.
|
||||||
- (void)clearContents;
|
- (void)clearContents;
|
||||||
- (void)clearFetchedData;
|
- (void)clearPreloadedData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object that describes the layout behavior of the ranged component (table view, collection view, etc.)
|
* An object that describes the layout behavior of the ranged component (table view, collection view, etc.)
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ static UIApplicationState __ApplicationState = UIApplicationStateActive;
|
|||||||
|
|
||||||
// Typically the preloadIndexPaths will be the largest, and be a superset of the others, though it may be disjoint.
|
// Typically the preloadIndexPaths will be the largest, and be a superset of the others, though it may be disjoint.
|
||||||
// Because allIndexPaths is an NSMutableOrderedSet, this adds the non-duplicate items /after/ the existing items.
|
// Because allIndexPaths is an NSMutableOrderedSet, this adds the non-duplicate items /after/ the existing items.
|
||||||
// This means that during iteration, we will first visit visible, then display, then fetch data nodes.
|
// This means that during iteration, we will first visit visible, then display, then preload nodes.
|
||||||
[allIndexPaths unionSet:displayIndexPaths];
|
[allIndexPaths unionSet:displayIndexPaths];
|
||||||
[allIndexPaths unionSet:preloadIndexPaths];
|
[allIndexPaths unionSet:preloadIndexPaths];
|
||||||
|
|
||||||
@@ -292,14 +292,14 @@ static UIApplicationState __ApplicationState = UIApplicationStateActive;
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If selfInterfaceState isn't visible, then visibleIndexPaths represents what /will/ be immediately visible at the
|
// If selfInterfaceState isn't visible, then visibleIndexPaths represents what /will/ be immediately visible at the
|
||||||
// instant we come onscreen. So, fetch data and display all of those things, but don't waste resources preloading yet.
|
// instant we come onscreen. So, preload and display all of those things, but don't waste resources preloading yet.
|
||||||
// We handle this as a separate case to minimize set operations for offscreen preloading, including containsObject:.
|
// We handle this as a separate case to minimize set operations for offscreen preloading, including containsObject:.
|
||||||
|
|
||||||
if ([allCurrentIndexPaths containsObject:indexPath]) {
|
if ([allCurrentIndexPaths containsObject:indexPath]) {
|
||||||
// DO NOT set Visible: even though these elements are in the visible range / "viewport",
|
// DO NOT set Visible: even though these elements are in the visible range / "viewport",
|
||||||
// our overall container object is itself not visible yet. The moment it becomes visible, we will run the condition above
|
// our overall container object is itself not visible yet. The moment it becomes visible, we will run the condition above
|
||||||
|
|
||||||
// Set Layout, Fetch Data
|
// Set Layout, Preload
|
||||||
interfaceState |= ASInterfaceStatePreload;
|
interfaceState |= ASInterfaceStatePreload;
|
||||||
|
|
||||||
if (rangeMode != ASLayoutRangeModeLowMemory) {
|
if (rangeMode != ASLayoutRangeModeLowMemory) {
|
||||||
@@ -501,7 +501,7 @@ static UIApplicationState __ApplicationState = UIApplicationStateActive;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clearFetchedData
|
- (void)clearPreloadedData
|
||||||
{
|
{
|
||||||
for (NSArray *section in [_dataSource completedNodes]) {
|
for (NSArray *section in [_dataSource completedNodes]) {
|
||||||
for (ASDisplayNode *node in section) {
|
for (ASDisplayNode *node in section) {
|
||||||
|
|||||||
@@ -156,6 +156,31 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyState(ASHierarchyStat
|
|||||||
*/
|
*/
|
||||||
- (void)recursivelyEnsureDisplaySynchronously:(BOOL)synchronously;
|
- (void)recursivelyEnsureDisplaySynchronously:(BOOL)synchronously;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Calls -didExitPreloadState on the receiver and its subnode hierarchy.
|
||||||
|
*
|
||||||
|
* @discussion Clears any memory-intensive preloaded content.
|
||||||
|
* This method is used to notify the node that it should purge any content that is both expensive to fetch and to
|
||||||
|
* retain in memory.
|
||||||
|
*
|
||||||
|
* @see [ASDisplayNode(Subclassing) didExitPreloadState] and [ASDisplayNode(Subclassing) didEnterPreloadState]
|
||||||
|
*/
|
||||||
|
- (void)recursivelyClearPreloadedData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Calls -didEnterPreloadState on the receiver and its subnode hierarchy.
|
||||||
|
*
|
||||||
|
* @discussion Fetches content from remote sources for the current node and all subnodes.
|
||||||
|
*
|
||||||
|
* @see [ASDisplayNode(Subclassing) didEnterPreloadState] and [ASDisplayNode(Subclassing) didExitPreloadState]
|
||||||
|
*/
|
||||||
|
- (void)recursivelyPreload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Triggers a recursive call to -didEnterPreloadState when the node has an interfaceState of ASInterfaceStatePreload
|
||||||
|
*/
|
||||||
|
- (void)setNeedsPreload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Allows a node to bypass all ensureDisplay passes. Defaults to NO.
|
* @abstract Allows a node to bypass all ensureDisplay passes. Defaults to NO.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides)
|
|||||||
ASDisplayNodeMethodOverrideTouchesCancelled = 1 << 1,
|
ASDisplayNodeMethodOverrideTouchesCancelled = 1 << 1,
|
||||||
ASDisplayNodeMethodOverrideTouchesEnded = 1 << 2,
|
ASDisplayNodeMethodOverrideTouchesEnded = 1 << 2,
|
||||||
ASDisplayNodeMethodOverrideTouchesMoved = 1 << 3,
|
ASDisplayNodeMethodOverrideTouchesMoved = 1 << 3,
|
||||||
ASDisplayNodeMethodOverrideLayoutSpecThatFits = 1 << 4
|
ASDisplayNodeMethodOverrideLayoutSpecThatFits = 1 << 4,
|
||||||
|
ASDisplayNodeMethodOverrideFetchData = 1 << 5,
|
||||||
|
ASDisplayNodeMethodOverrideClearFetchedData = 1 << 6
|
||||||
};
|
};
|
||||||
|
|
||||||
FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification;
|
FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification;
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
|||||||
@interface ASTestDisplayNode : ASDisplayNode
|
@interface ASTestDisplayNode : ASDisplayNode
|
||||||
@property (nonatomic, copy) void (^willDeallocBlock)(__unsafe_unretained ASTestDisplayNode *node);
|
@property (nonatomic, copy) void (^willDeallocBlock)(__unsafe_unretained ASTestDisplayNode *node);
|
||||||
@property (nonatomic, copy) CGSize(^calculateSizeBlock)(ASTestDisplayNode *node, CGSize size);
|
@property (nonatomic, copy) CGSize(^calculateSizeBlock)(ASTestDisplayNode *node, CGSize size);
|
||||||
@property (nonatomic) BOOL hasFetchedData;
|
|
||||||
|
|
||||||
@property (nonatomic, nullable) UIGestureRecognizer *gestureRecognizer;
|
@property (nonatomic, nullable) UIGestureRecognizer *gestureRecognizer;
|
||||||
@property (nonatomic, nullable) id idGestureRecognizer;
|
@property (nonatomic, nullable) id idGestureRecognizer;
|
||||||
@@ -99,6 +98,7 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
|||||||
@property (nonatomic) BOOL displayRangeStateChangedToYES;
|
@property (nonatomic) BOOL displayRangeStateChangedToYES;
|
||||||
@property (nonatomic) BOOL displayRangeStateChangedToNO;
|
@property (nonatomic) BOOL displayRangeStateChangedToNO;
|
||||||
|
|
||||||
|
@property (nonatomic) BOOL hasPreloaded;
|
||||||
@property (nonatomic) BOOL preloadStateChangedToYES;
|
@property (nonatomic) BOOL preloadStateChangedToYES;
|
||||||
@property (nonatomic) BOOL preloadStateChangedToNO;
|
@property (nonatomic) BOOL preloadStateChangedToNO;
|
||||||
@end
|
@end
|
||||||
@@ -113,18 +113,6 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
|||||||
return _calculateSizeBlock ? _calculateSizeBlock(self, constrainedSize) : CGSizeZero;
|
return _calculateSizeBlock ? _calculateSizeBlock(self, constrainedSize) : CGSizeZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
|
||||||
{
|
|
||||||
[super fetchData];
|
|
||||||
self.hasFetchedData = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)clearFetchedData
|
|
||||||
{
|
|
||||||
[super clearFetchedData];
|
|
||||||
self.hasFetchedData = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)didEnterDisplayState
|
- (void)didEnterDisplayState
|
||||||
{
|
{
|
||||||
[super didEnterDisplayState];
|
[super didEnterDisplayState];
|
||||||
@@ -141,6 +129,7 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
|||||||
{
|
{
|
||||||
[super didEnterPreloadState];
|
[super didEnterPreloadState];
|
||||||
self.preloadStateChangedToYES = YES;
|
self.preloadStateChangedToYES = YES;
|
||||||
|
self.hasPreloaded = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didExitPreloadState
|
- (void)didExitPreloadState
|
||||||
@@ -1738,76 +1727,76 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check that nodes who have no cell node (no range controller)
|
// Check that nodes who have no cell node (no range controller)
|
||||||
// do get their `fetchData` called, and they do report
|
// do get their `preload` called, and they do report
|
||||||
// the fetch data interface state.
|
// the preload interface state.
|
||||||
- (void)testInterfaceStateForNonCellNode
|
- (void)testInterfaceStateForNonCellNode
|
||||||
{
|
{
|
||||||
ASTestWindow *window = [ASTestWindow new];
|
ASTestWindow *window = [ASTestWindow new];
|
||||||
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
||||||
XCTAssert(node.interfaceState == ASInterfaceStateNone);
|
XCTAssert(node.interfaceState == ASInterfaceStateNone);
|
||||||
XCTAssert(!node.hasFetchedData);
|
XCTAssert(!node.hasPreloaded);
|
||||||
|
|
||||||
[window addSubview:node.view];
|
[window addSubview:node.view];
|
||||||
XCTAssert(node.hasFetchedData);
|
XCTAssert(node.hasPreloaded);
|
||||||
XCTAssert(node.interfaceState == ASInterfaceStateInHierarchy);
|
XCTAssert(node.interfaceState == ASInterfaceStateInHierarchy);
|
||||||
|
|
||||||
[node.view removeFromSuperview];
|
[node.view removeFromSuperview];
|
||||||
// We don't want to call -clearFetchedData on nodes that aren't being managed by a range controller.
|
// We don't want to call -didExitPreloadState on nodes that aren't being managed by a range controller.
|
||||||
// Otherwise we get flashing behavior from normal UIKit manipulations like navigation controller push / pop.
|
// Otherwise we get flashing behavior from normal UIKit manipulations like navigation controller push / pop.
|
||||||
// Still, the interfaceState should be None to reflect the current state of the node.
|
// Still, the interfaceState should be None to reflect the current state of the node.
|
||||||
// We just don't proactively clear contents or fetched data for this state transition.
|
// We just don't proactively clear contents or fetched data for this state transition.
|
||||||
XCTAssert(node.hasFetchedData);
|
XCTAssert(node.hasPreloaded);
|
||||||
XCTAssert(node.interfaceState == ASInterfaceStateNone);
|
XCTAssert(node.interfaceState == ASInterfaceStateNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that nodes who have no cell node (no range controller)
|
// Check that nodes who have no cell node (no range controller)
|
||||||
// do get their `fetchData` called, and they do report
|
// do get their `preload` called, and they do report
|
||||||
// the fetch data interface state.
|
// the preload interface state.
|
||||||
- (void)testInterfaceStateForCellNode
|
- (void)testInterfaceStateForCellNode
|
||||||
{
|
{
|
||||||
ASCellNode *cellNode = [ASCellNode new];
|
ASCellNode *cellNode = [ASCellNode new];
|
||||||
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
||||||
XCTAssert(node.interfaceState == ASInterfaceStateNone);
|
XCTAssert(node.interfaceState == ASInterfaceStateNone);
|
||||||
XCTAssert(!node.hasFetchedData);
|
XCTAssert(!node.hasPreloaded);
|
||||||
|
|
||||||
// Simulate range handler updating cell node.
|
// Simulate range handler updating cell node.
|
||||||
[cellNode addSubnode:node];
|
[cellNode addSubnode:node];
|
||||||
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
||||||
XCTAssert(node.hasFetchedData);
|
XCTAssert(node.hasPreloaded);
|
||||||
XCTAssert(node.interfaceState == ASInterfaceStatePreload);
|
XCTAssert(node.interfaceState == ASInterfaceStatePreload);
|
||||||
|
|
||||||
// If the node goes into a view it should not adopt the `InHierarchy` state.
|
// If the node goes into a view it should not adopt the `InHierarchy` state.
|
||||||
ASTestWindow *window = [ASTestWindow new];
|
ASTestWindow *window = [ASTestWindow new];
|
||||||
[window addSubview:cellNode.view];
|
[window addSubview:cellNode.view];
|
||||||
XCTAssert(node.hasFetchedData);
|
XCTAssert(node.hasPreloaded);
|
||||||
XCTAssert(node.interfaceState == ASInterfaceStateInHierarchy);
|
XCTAssert(node.interfaceState == ASInterfaceStateInHierarchy);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testSetNeedsDataFetchImmediateState
|
- (void)testSetNeedsPreloadImmediateState
|
||||||
{
|
{
|
||||||
ASCellNode *cellNode = [ASCellNode new];
|
ASCellNode *cellNode = [ASCellNode new];
|
||||||
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
||||||
[cellNode addSubnode:node];
|
[cellNode addSubnode:node];
|
||||||
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
||||||
node.hasFetchedData = NO;
|
node.hasPreloaded = NO;
|
||||||
[cellNode setNeedsDataFetch];
|
[cellNode setNeedsPreload];
|
||||||
XCTAssert(node.hasFetchedData);
|
XCTAssert(node.hasPreloaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testFetchDataExitingAndEnteringRange
|
- (void)testPreloadExitingAndEnteringRange
|
||||||
{
|
{
|
||||||
ASCellNode *cellNode = [ASCellNode new];
|
ASCellNode *cellNode = [ASCellNode new];
|
||||||
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
ASTestDisplayNode *node = [ASTestDisplayNode new];
|
||||||
[cellNode addSubnode:node];
|
[cellNode addSubnode:node];
|
||||||
[cellNode setHierarchyState:ASHierarchyStateRangeManaged];
|
[cellNode setHierarchyState:ASHierarchyStateRangeManaged];
|
||||||
|
|
||||||
// Simulate enter range, fetch data, exit range
|
// Simulate enter range, preload, exit range
|
||||||
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
||||||
[cellNode exitInterfaceState:ASInterfaceStatePreload];
|
[cellNode exitInterfaceState:ASInterfaceStatePreload];
|
||||||
node.hasFetchedData = NO;
|
node.hasPreloaded = NO;
|
||||||
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
[cellNode enterInterfaceState:ASInterfaceStatePreload];
|
||||||
|
|
||||||
XCTAssert(node.hasFetchedData);
|
XCTAssert(node.hasPreloaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testInitWithViewClass
|
- (void)testInitWithViewClass
|
||||||
@@ -2070,8 +2059,8 @@ static bool stringContainsPointer(NSString *description, id p) {
|
|||||||
|
|
||||||
XCTAssertTrue((node.interfaceState & ASInterfaceStatePreload) == ASInterfaceStatePreload);
|
XCTAssertTrue((node.interfaceState & ASInterfaceStatePreload) == ASInterfaceStatePreload);
|
||||||
XCTAssertTrue((subnode.interfaceState & ASInterfaceStatePreload) == ASInterfaceStatePreload);
|
XCTAssertTrue((subnode.interfaceState & ASInterfaceStatePreload) == ASInterfaceStatePreload);
|
||||||
XCTAssertTrue(node.hasFetchedData);
|
XCTAssertTrue(node.hasPreloaded);
|
||||||
XCTAssertTrue(subnode.hasFetchedData);
|
XCTAssertTrue(subnode.hasPreloaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
XCTAssertNil(_videoNode.player);
|
XCTAssertNil(_videoNode.player);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testPlayerIsCreatedAsynchronouslyInFetchData
|
- (void)testPlayerIsCreatedAsynchronouslyInPreload
|
||||||
{
|
{
|
||||||
AVAsset *asset = _firstAsset;
|
AVAsset *asset = _firstAsset;
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
XCTAssertNotNil(_videoNode.player);
|
XCTAssertNotNil(_videoNode.player);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testPlayerIsCreatedAsynchronouslyInFetchDataWithURL
|
- (void)testPlayerIsCreatedAsynchronouslyInPreloadWithURL
|
||||||
{
|
{
|
||||||
AVAsset *asset = [AVAsset assetWithURL:_url];
|
AVAsset *asset = [AVAsset assetWithURL:_url];
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@
|
|||||||
XCTAssertNotEqual(firstImage, _videoNode.image);
|
XCTAssertNotEqual(firstImage, _videoNode.image);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testClearingFetchedContentShouldClearAssetData
|
- (void)testClearingPreloadedContentShouldClearAssetData
|
||||||
{
|
{
|
||||||
AVAsset *asset = _firstAsset;
|
AVAsset *asset = _firstAsset;
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@
|
|||||||
[[[videoNodeMock expect] andForwardToRealObject] prepareToPlayAsset:assetMock withKeys:_requestedKeys];
|
[[[videoNodeMock expect] andForwardToRealObject] prepareToPlayAsset:assetMock withKeys:_requestedKeys];
|
||||||
|
|
||||||
_videoNode.asset = assetMock;
|
_videoNode.asset = assetMock;
|
||||||
[_videoNode fetchData];
|
[_videoNode didEnterPreloadState];
|
||||||
[_videoNode setVideoPlaceholderImage:[[UIImage alloc] init]];
|
[_videoNode setVideoPlaceholderImage:[[UIImage alloc] init]];
|
||||||
|
|
||||||
[videoNodeMock verifyWithDelay:1.0f];
|
[videoNodeMock verifyWithDelay:1.0f];
|
||||||
@@ -407,7 +407,7 @@
|
|||||||
XCTAssertNotNil(_videoNode.currentItem);
|
XCTAssertNotNil(_videoNode.currentItem);
|
||||||
XCTAssertNotNil(_videoNode.image);
|
XCTAssertNotNil(_videoNode.image);
|
||||||
|
|
||||||
[_videoNode clearFetchedData];
|
[_videoNode didExitPreloadState];
|
||||||
XCTAssertNil(_videoNode.player);
|
XCTAssertNil(_videoNode.player);
|
||||||
XCTAssertNil(_videoNode.currentItem);
|
XCTAssertNil(_videoNode.currentItem);
|
||||||
XCTAssertNil(_videoNode.image);
|
XCTAssertNil(_videoNode.image);
|
||||||
|
|||||||
Reference in New Issue
Block a user