diff --git a/AsyncDisplayKit/ASNetworkImageNode.h b/AsyncDisplayKit/ASNetworkImageNode.h index dddc0c426c..149f12b99b 100644 --- a/AsyncDisplayKit/ASNetworkImageNode.h +++ b/AsyncDisplayKit/ASNetworkImageNode.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN @interface ASNetworkImageNode : ASImageNode /** - * The designated initializer. Cache and Downloader are WEAK references. + * The designated initializer. Cache and Downloader are WEAK references. * * @param cache The object that implements a cache of images for the image node. Weak reference. * @param downloader The object that implements image downloading for the image node. Must not be nil. Weak reference. @@ -38,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithCache:(nullable id)cache downloader:(id)downloader NS_DESIGNATED_INITIALIZER; /** - * Convenience initialiser. + * Convenience initializer. * * @return An ASNetworkImageNode configured to use the NSURLSession-powered ASBasicImageDownloader, and no extra cache. */ @@ -49,6 +49,17 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nullable, nonatomic, weak, readwrite) id delegate; +/** + * The image to display. + * + * @discussion By setting an image to the image property the ASNetworkImageNode will act like a plain ASImageNode. + * As soon as the URL is set the ASNetworkImageNode will act like an ASNetworkImageNode and the image property + * will be managed internally. This means the image property will be cleared out and replaced by the placeholder + * () image while loading and the final image after the new image data was downloaded and processed. + * If you want to use a placholder image functionality use the defaultImage property instead. + */ +@property (nullable, nonatomic, strong) UIImage *image; + /** * A placeholder image to display while the URL is loading. */ @@ -57,7 +68,9 @@ NS_ASSUME_NONNULL_BEGIN /** * The URL of a new image to download and display. * - * @discussion Changing this property will reset the displayed image to a placeholder () while loading. + * @discussion By setting an URL, the image property of this node will be managed internally. This means previously + * directly set images to the image property will be cleared out and replaced by the placeholder () image + * while loading and the final image after the new image data was downloaded and processed. */ @property (nullable, nonatomic, strong, readwrite) NSURL *URL; @@ -65,8 +78,11 @@ NS_ASSUME_NONNULL_BEGIN * Download and display a new image. * * @param URL The URL of a new image to download and display. - * * @param reset Whether to display a placeholder () while loading the new image. + * + * @discussion By setting an URL, the image property of this node will be managed internally. This means previously + * directly set images to the image property will be cleared out and replaced by the placeholder () image + * while loading and the final image after the new image data was downloaded and processed. */ - (void)setURL:(nullable NSURL *)URL resetToDefault:(BOOL)reset; diff --git a/AsyncDisplayKit/ASNetworkImageNode.mm b/AsyncDisplayKit/ASNetworkImageNode.mm index 5b0d3d6cb4..87ab85031b 100755 --- a/AsyncDisplayKit/ASNetworkImageNode.mm +++ b/AsyncDisplayKit/ASNetworkImageNode.mm @@ -73,6 +73,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; @implementation ASNetworkImageNode +@dynamic image; + - (instancetype)initWithCache:(id)cache downloader:(id)downloader { if (!(self = [super init])) @@ -121,20 +123,13 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; /// Setter for public image property. It has the side effect to set an internal _imageWasSetExternally that prevents setting an image internally. Setting an image internally should happen with the _setImage: method - (void)setImage:(UIImage *)image { - __instanceLock__.lock(); - -#ifdef DEBUG - if (_URL != nil) { - NSLog(@"Setting the image directly on an %@ and setting and setting an URL is not supported. If you want to use a placeholder image please use defaultImage .", NSStringFromClass([self class])); - } -#endif + ASDN::MutexLocker l(__instanceLock__); _imageWasSetExternally = (image != nil); if (_imageWasSetExternally) { - [self __cancelDownloadAndClearImage]; + [self _cancelDownloadAndClearImage]; _URL = nil; } - __instanceLock__.unlock(); [self _setImage:image]; } @@ -153,11 +148,6 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; { ASDN::MutexLocker l(__instanceLock__); -#ifdef DEBUG - if (_imageWasSetExternally) { - NSLog(@"Setting the image directly on an %@ and setting and setting an URL is not supported. If you want to use a placeholder image please use defaultImage .", NSStringFromClass([self class])); - } -#endif _imageWasSetExternally = NO; if (ASObjectIsEqual(URL, _URL)) { @@ -352,7 +342,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; return; } - [self __cancelDownloadAndClearImage]; + [self _cancelDownloadAndClearImage]; } } @@ -419,7 +409,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; _downloadIdentifierForProgressBlock = newDownloadIDForProgressBlock; } -- (void)__cancelDownloadAndClearImage +- (void)_cancelDownloadAndClearImage { [self _cancelImageDownload]; [self _clearImage]; @@ -428,6 +418,20 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; } } +- (void)_cancelImageDownload +{ + if (!_downloadIdentifier) { + return; + } + + if (_downloadIdentifier) { + [_downloader cancelImageDownloadForIdentifier:_downloadIdentifier]; + } + _downloadIdentifier = nil; + + _cacheUUID = nil; +} + - (void)_clearImage { // Destruction of bigger images on the main thread can be expensive @@ -449,20 +453,6 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; }); } -- (void)_cancelImageDownload -{ - if (!_downloadIdentifier) { - return; - } - - if (_downloadIdentifier) { - [_downloader cancelImageDownloadForIdentifier:_downloadIdentifier]; - } - _downloadIdentifier = nil; - - _cacheUUID = nil; -} - - (void)_downloadImageWithCompletion:(void (^)(id imageContainer, NSError*, id downloadIdentifier))finished { ASPerformBlockOnBackgroundThread(^{