BOOL _downloadsIntermediateImages; // Defaults to NO.
ASDN::Mutex _imageIdentifiersLock;
NSArray *_imageIdentifiers;
id _loadedImageIdentifier;
id _loadingImageIdentifier;
id _displayedImageIdentifier;
__weak NSOperation *_phImageRequestOperation;
// Networking.
ASDN::RecursiveMutex _downloadIdentifierLock;
id _downloadIdentifier;
// Properties
ASDN::RecursiveMutex _propertyLock;
BOOL _shouldRenderProgressImages;
//set on init only
BOOL _downloaderSupportsNewProtocol;
BOOL _downloaderImplementsSetProgress;
BOOL _downloaderImplementsSetPriority;
BOOL _cacheSupportsNewProtocol;
BOOL _cacheSupportsClearing;
}
//! @abstract Read-write redeclaration of property declared in ASMultiplexImageNode.h.
@property (nonatomic, readwrite, copy) id loadedImageIdentifier;
//! @abstract The image identifier that's being loaded by _loadNextImageWithCompletion:.
@property (nonatomic, readwrite, copy) id loadingImageIdentifier;
/**
@abstract Returns the next image identifier that should be downloaded.
@discussion This method obeys and reflects the value of `downloadsIntermediateImages`.
@result The next image identifier, from `_imageIdentifiers`, that should be downloaded, or nil if no image should be downloaded next.
*/
- (id)_nextImageIdentifierToDownload;
/**
@abstract Returns the best image that is immediately available from our datasource without downloading or hitting the cache.
@param imageIdentifierOut Upon return, the image identifier for the returned image; nil otherwise.
@discussion This method exclusively uses the data source's -multiplexImageNode:imageForIdentifier: method to return images. It does not fetch from the cache or kick off downloading.
@result The best UIImage available immediately; nil if no image is immediately available.
@abstract Loads and displays the next image in the receiver's loading sequence.
@discussion This method obeys `downloadsIntermediateImages`. This method has no effect if nothing further should be loaded, as indicated by `_nextImageIdentifierToDownload`. This method will load the next image from the data-source, if possible; otherwise, the session's image cache will be queried for the desired image, and as a last resort, the image will be downloaded.
*/
- (void)_loadNextImage;
/**
@abstract Fetches the image corresponding to the given imageIdentifier from the given URL from the session's image cache.
@param imageIdentifier The identifier for the image to be fetched. May not be nil.
@param imageURL The URL of the image to fetch. May not be nil.
@param completionBlock The block to be performed when the image has been fetched from the cache, if possible. May not be nil.
@param image The image fetched from the cache, if any.
@discussion This method queries both the session's in-memory and on-disk caches (with preference for the in-memory cache).
ASDisplayNodeAssert([downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)] || [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:)], @"downloader must respond to either downloadImageWithURL:callbackQueue:downloadProgress:completion: or downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:.");
ASDisplayNodeAssert(cache == nil || [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)] || [cache respondsToSelector:@selector(fetchCachedImageWithURL:callbackQueue:completion:)], @"cacher must respond to either cachedImageWithURL:callbackQueue:completion: or fetchCachedImageWithURL:callbackQueue:completion:");
// Note that we're using the params here instead of self.image and _displayedImageIdentifier because those can change before the async block below executes.
// If you don't set this, iOS will sometimes infer NSQualityOfServiceUserInteractive and promote the entire queue to that level, damaging system responsiveness
// If we failed to load, we stop the loading process.
// Note that if we bailed before we began downloading because the best identifier changed, we don't bail, but rather just begin loading the best image identifier.
if (error && !([error.domain isEqual:ASMultiplexImageNodeErrorDomain] && error.code == ASMultiplexImageNodeErrorCodeBestImageIdentifierChanged))
// Update our image if we got one, or if we're not supposed to display one at all.
// We explicitly perform this check because our datasource often doesn't give back immediately available images, even though we might have downloaded one already.
// Because we seed this call with bestImmediatelyAvailableImageFromDataSource, we must be careful not to trample an existing image.