mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Add assertion against externally setting .image in specific ASImageNode subclasses
This commit is contained in:
@@ -204,6 +204,7 @@
|
||||
6907C2591DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */; };
|
||||
6907C25A1DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */; };
|
||||
69127CFE1DD2B387004BF6E2 /* ASEventLog.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 696F01EA1DD2AF450049FBD5 /* ASEventLog.h */; };
|
||||
69309D461DF3B1B50089FA48 /* ASImageNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 69309D451DF3B1B50089FA48 /* ASImageNode+Private.h */; };
|
||||
693117CE1DC7C72700DE4784 /* ASDisplayNode+Deprecated.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 683489271D70DE3400327501 /* ASDisplayNode+Deprecated.h */; };
|
||||
69527B121DC84292004785FB /* ASLayoutElementStylePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 69527B111DC84292004785FB /* ASLayoutElementStylePrivate.h */; };
|
||||
6959433E1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */; };
|
||||
@@ -1002,6 +1003,7 @@
|
||||
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASVisibilityProtocols.m; sourceTree = "<group>"; };
|
||||
6907C2561DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASObjectDescriptionHelpers.h; sourceTree = "<group>"; };
|
||||
6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASObjectDescriptionHelpers.m; sourceTree = "<group>"; };
|
||||
69309D451DF3B1B50089FA48 /* ASImageNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+Private.h"; sourceTree = "<group>"; };
|
||||
69527B111DC84292004785FB /* ASLayoutElementStylePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutElementStylePrivate.h; path = AsyncDisplayKit/Layout/ASLayoutElementStylePrivate.h; sourceTree = SOURCE_ROOT; };
|
||||
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayout.mm; sourceTree = "<group>"; };
|
||||
6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeLayout.h; sourceTree = "<group>"; };
|
||||
@@ -1609,6 +1611,7 @@
|
||||
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */,
|
||||
058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */,
|
||||
058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */,
|
||||
69309D451DF3B1B50089FA48 /* ASImageNode+Private.h */,
|
||||
ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */,
|
||||
ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.m */,
|
||||
69C4CAF51DA3147000B1EC9B /* ASLayoutElementStylePrivate.h */,
|
||||
@@ -1857,6 +1860,7 @@
|
||||
34EFC7631B701CBF00AD841F /* ASCenterLayoutSpec.h in Headers */,
|
||||
9C70F20C1CDBE9B6007D6C76 /* ASCollectionDataController.h in Headers */,
|
||||
18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */,
|
||||
69309D461DF3B1B50089FA48 /* ASImageNode+Private.h in Headers */,
|
||||
9C8898BD1C738BB800D6B02E /* ASTextKitFontSizeAdjuster.h in Headers */,
|
||||
B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */,
|
||||
ACE87A2C1D73696800D7FF06 /* ASSectionContext.h in Headers */,
|
||||
|
||||
@@ -199,6 +199,11 @@ struct ASImageNodeDrawParameters {
|
||||
#pragma mark - Setter / Getter
|
||||
|
||||
- (void)setImage:(UIImage *)image
|
||||
{
|
||||
[self __setImage:image];
|
||||
}
|
||||
|
||||
- (void)__setImage:(UIImage *)image
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
if (!ASObjectIsEqual(_image, image)) {
|
||||
|
||||
@@ -11,16 +11,17 @@
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import "ASMultiplexImageNode.h"
|
||||
#import "ASImageNode+Private.h"
|
||||
#import <AssetsLibrary/AssetsLibrary.h>
|
||||
|
||||
#import "ASAvailability.h"
|
||||
#import "ASDisplayNode+Subclasses.h"
|
||||
#import "ASDisplayNode+FrameworkPrivate.h"
|
||||
#import "ASDisplayNodeExtras.h"
|
||||
#import "ASLog.h"
|
||||
#import "ASPhotosFrameworkImageRequest.h"
|
||||
#import "ASEqualityHelpers.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
#import "ASDisplayNodeExtras.h"
|
||||
|
||||
#if !AS_IOS8_SDK_OR_LATER
|
||||
#error ASMultiplexImageNode can be used on iOS 7, but must be linked against the iOS 8 SDK.
|
||||
@@ -233,7 +234,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
||||
|
||||
// setting this to nil makes the node fetch images the next time its display starts
|
||||
_loadedImageIdentifier = nil;
|
||||
self.image = nil;
|
||||
[self __setImage:nil];
|
||||
}
|
||||
|
||||
- (void)didEnterPreloadState
|
||||
@@ -325,6 +326,12 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
||||
|
||||
#pragma mark - Core
|
||||
|
||||
- (void)setImage:(UIImage *)image
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"Setting the image directly to an ASMultiplexImageNode is not allowed.");
|
||||
[self __setImage:image];
|
||||
}
|
||||
|
||||
- (void)setDelegate:(id <ASMultiplexImageNodeDelegate>)delegate
|
||||
{
|
||||
if (_delegate == delegate)
|
||||
@@ -520,7 +527,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
||||
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||
return;
|
||||
}
|
||||
strongSelf.image = progressImage;
|
||||
[self __setImage:progressImage];
|
||||
};
|
||||
}
|
||||
[_downloader setProgressImageBlock:progress callbackQueue:dispatch_get_main_queue() withDownloadIdentifier:_downloadIdentifier];
|
||||
@@ -538,7 +545,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
||||
if (shouldReleaseImageOnBackgroundThread) {
|
||||
ASPerformBackgroundDeallocation(image);
|
||||
}
|
||||
self.image = nil;
|
||||
[self __setImage:nil];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -867,7 +874,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
||||
UIImage *previousImage = self.image;
|
||||
|
||||
self.loadedImageIdentifier = imageIdentifier;
|
||||
self.image = image;
|
||||
[self __setImage:image];
|
||||
|
||||
if (_delegateFlags.updatedImage) {
|
||||
[_delegate multiplexImageNode:self didUpdateImage:image withIdentifier:imageIdentifier fromImage:previousImage withIdentifier:previousIdentifier];
|
||||
|
||||
@@ -9,15 +9,16 @@
|
||||
//
|
||||
|
||||
#import "ASNetworkImageNode.h"
|
||||
#import "ASImageNode+Private.h"
|
||||
|
||||
#import "ASBasicImageDownloader.h"
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
#import "ASDisplayNodeExtras.h"
|
||||
#import "ASDisplayNode+Subclasses.h"
|
||||
#import "ASDisplayNode+FrameworkPrivate.h"
|
||||
#import "ASEqualityHelpers.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
#import "ASImageContainerProtocolCategories.h"
|
||||
#import "ASDisplayNodeExtras.h"
|
||||
|
||||
#if PIN_REMOTE_IMAGE
|
||||
#import "ASPINRemoteImageDownloader.h"
|
||||
@@ -67,6 +68,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
unsigned int cacheSupportsSynchronousFetch:1;
|
||||
} _cacheFlags;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASNetworkImageNode
|
||||
@@ -116,6 +118,12 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
#pragma mark - Public methods -- must lock
|
||||
|
||||
- (void)setImage:(UIImage *)image
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"Setting the image directly to an ASNetworkImageNode is not allowed. Please either use the defaultImage property or move to an ASImageNode");
|
||||
[self __setImage:image];
|
||||
}
|
||||
|
||||
- (void)setURL:(NSURL *)URL
|
||||
{
|
||||
[self setURL:URL resetToDefault:YES];
|
||||
@@ -136,7 +144,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
BOOL hasURL = _URL == nil;
|
||||
if (reset || hasURL) {
|
||||
self.image = _defaultImage;
|
||||
[self __setImage:_defaultImage];
|
||||
/* We want to maintain the order that currentImageQuality is set regardless of the calling thread,
|
||||
so always use a dispatch_async to ensure that we queue the operations in the correct order.
|
||||
(see comment in displayDidFinish) */
|
||||
@@ -171,7 +179,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.currentImageQuality = hasURL ? 0.0 : 1.0;
|
||||
});
|
||||
self.image = defaultImage;
|
||||
[self __setImage:defaultImage];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +264,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
if (_imageLoaded == NO && _URL && _downloadIdentifier == nil) {
|
||||
UIImage *result = [[_cache synchronouslyFetchedCachedImageWithURL:_URL] asdk_image];
|
||||
if (result) {
|
||||
self.image = result;
|
||||
[self __setImage:result];
|
||||
_imageLoaded = YES;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_currentImageQuality = 1.0;
|
||||
@@ -340,7 +348,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
if (ASObjectIsEqual(_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||
return;
|
||||
}
|
||||
self.image = progressImage;
|
||||
[self __setImage:progressImage];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// See comment in -displayDidFinish for why this must be dispatched to main
|
||||
self.currentImageQuality = progress;
|
||||
@@ -396,7 +404,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
ASPerformBackgroundDeallocation(image);
|
||||
}
|
||||
self.animatedImage = nil;
|
||||
self.image = _defaultImage;
|
||||
[self __setImage:_defaultImage];
|
||||
_imageLoaded = NO;
|
||||
// See comment in -displayDidFinish for why this must be dispatched to main
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@@ -456,7 +464,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.shouldCacheImage) {
|
||||
self.image = [UIImage imageNamed:_URL.path.lastPathComponent];
|
||||
[self __setImage:[UIImage imageNamed:_URL.path.lastPathComponent]];
|
||||
} else {
|
||||
// First try to load the path directly, for efficiency assuming a developer who
|
||||
// doesn't want caching is trying to be as minimal as possible.
|
||||
@@ -486,7 +494,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
if (animatedImage != nil) {
|
||||
self.animatedImage = animatedImage;
|
||||
} else {
|
||||
self.image = nonAnimatedImage;
|
||||
[self __setImage:nonAnimatedImage];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +530,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
if ([imageContainer asdk_animatedImageData] && _downloaderFlags.downloaderImplementsAnimatedImage) {
|
||||
strongSelf.animatedImage = [_downloader animatedImageWithData:[imageContainer asdk_animatedImageData]];
|
||||
} else {
|
||||
strongSelf.image = [imageContainer asdk_image];
|
||||
[strongSelf __setImage:[imageContainer asdk_image]];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
strongSelf->_currentImageQuality = 1.0;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#import "ASEqualityHelpers.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
#import "ASDisplayNodeExtras.h"
|
||||
#import "ASImageNode+Private.h"
|
||||
|
||||
static BOOL ASAssetIsEqual(AVAsset *asset1, AVAsset *asset2) {
|
||||
return ASObjectIsEqual(asset1, asset2)
|
||||
@@ -300,7 +301,7 @@ static NSString * const kRate = @"rate";
|
||||
if (image != nil) {
|
||||
self.contentMode = ASContentModeFromVideoGravity(_gravity);
|
||||
}
|
||||
self.image = image;
|
||||
[self __setImage:image];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
|
||||
22
AsyncDisplayKit/Private/ASImageNode+Private.h
Normal file
22
AsyncDisplayKit/Private/ASImageNode+Private.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// ASImageNode+Private.h
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Michael Schneider on 12/3/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma mark - ASImageNode
|
||||
|
||||
#import "ASImageNode.h"
|
||||
|
||||
@interface ASImageNode (Private)
|
||||
|
||||
/*
|
||||
* Set the image property of the ASImageNode. Subclasses like ASNetworkImageNode do not allow setting the
|
||||
* image property directly and throw an assertion. There still needs to be a way for subclasses of
|
||||
* ASNetworkImageNode to set the image.
|
||||
*/
|
||||
- (void)__setImage:(UIImage *)image;
|
||||
|
||||
@end
|
||||
@@ -302,4 +302,10 @@
|
||||
[mockDelegate verify];
|
||||
}
|
||||
|
||||
@end
|
||||
- (void)testThatSettingAnImageExternallyWillThrow
|
||||
{
|
||||
ASMultiplexImageNode *multiplexImageNode = [[ASMultiplexImageNode alloc] init];
|
||||
XCTAssertThrows(multiplexImageNode.image = [UIImage imageNamed:@""]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -71,6 +71,12 @@
|
||||
[downloader verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)testThatSettingAnImageExternallyWillThrow
|
||||
{
|
||||
ASNetworkImageNode *networkImageNode = [[ASNetworkImageNode alloc] init];
|
||||
XCTAssertThrows(networkImageNode.image = [UIImage imageNamed:@""]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASTestImageCache
|
||||
|
||||
Reference in New Issue
Block a user