From 6bab2de69a98308595a02bda9374be896e4a51f6 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Sat, 9 Mar 2019 15:19:25 +0800 Subject: [PATCH] Move some internal classes into private header files, make it easy to maintain the code --- .../SDWebImage Demo.xcodeproj/project.pbxproj | 16 +- SDWebImage.xcodeproj/project.pbxproj | 72 ++++++++ .../Private/NSBezierPath+RoundedCorners.h | 24 +++ .../Private/NSBezierPath+RoundedCorners.m | 42 +++++ SDWebImage/Private/SDImageAPNGCoder+Private.h | 17 ++ SDWebImage/Private/SDImageAssetManager.h | 23 +++ SDWebImage/Private/SDImageAssetManager.m | 157 +++++++++++++++++ .../Private/SDImageCachesManagerOperation.h | 21 +++ .../Private/SDImageCachesManagerOperation.m | 60 +++++++ SDWebImage/Private/SDImageGIFCoder+Private.h | 16 ++ SDWebImage/Private/SDWeakProxy.h | 19 ++ SDWebImage/Private/SDWeakProxy.m | 79 +++++++++ SDWebImage/Private/UIColor+HexString.h | 18 ++ SDWebImage/Private/UIColor+HexString.m | 42 +++++ SDWebImage/SDAnimatedImage.m | 164 +----------------- SDWebImage/SDAnimatedImageRep.m | 17 +- SDWebImage/SDAnimatedImageView.m | 80 +-------- SDWebImage/SDImageCachesManager.m | 63 +------ SDWebImage/SDImageTransformer.m | 43 +---- SDWebImage/UIImage+Transform.m | 41 +---- .../project.pbxproj | 8 +- 21 files changed, 609 insertions(+), 413 deletions(-) create mode 100644 SDWebImage/Private/NSBezierPath+RoundedCorners.h create mode 100644 SDWebImage/Private/NSBezierPath+RoundedCorners.m create mode 100644 SDWebImage/Private/SDImageAPNGCoder+Private.h create mode 100644 SDWebImage/Private/SDImageAssetManager.h create mode 100644 SDWebImage/Private/SDImageAssetManager.m create mode 100644 SDWebImage/Private/SDImageCachesManagerOperation.h create mode 100644 SDWebImage/Private/SDImageCachesManagerOperation.m create mode 100644 SDWebImage/Private/SDImageGIFCoder+Private.h create mode 100644 SDWebImage/Private/SDWeakProxy.h create mode 100644 SDWebImage/Private/SDWeakProxy.m create mode 100644 SDWebImage/Private/UIColor+HexString.h create mode 100644 SDWebImage/Private/UIColor+HexString.m diff --git a/Examples/SDWebImage Demo.xcodeproj/project.pbxproj b/Examples/SDWebImage Demo.xcodeproj/project.pbxproj index 977ec945..5f85d8bd 100644 --- a/Examples/SDWebImage Demo.xcodeproj/project.pbxproj +++ b/Examples/SDWebImage Demo.xcodeproj/project.pbxproj @@ -634,7 +634,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage OSX Demo/Pods-SDWebImage OSX Demo-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-SDWebImage OSX Demo/Pods-SDWebImage OSX Demo-frameworks.sh", "${BUILT_PRODUCTS_DIR}/SDWebImage-macOS/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-macOS/SDWebImageWebPCoder.framework", "${BUILT_PRODUCTS_DIR}/libwebp-macOS/libwebp.framework", @@ -647,7 +647,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage OSX Demo/Pods-SDWebImage OSX Demo-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage OSX Demo/Pods-SDWebImage OSX Demo-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 8425DD76050A8A49F8DAF736 /* [CP] Embed Pods Frameworks */ = { @@ -656,7 +656,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh", "${BUILT_PRODUCTS_DIR}/SDWebImage-iOS/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-iOS/SDWebImageWebPCoder.framework", "${BUILT_PRODUCTS_DIR}/libwebp-iOS/libwebp.framework", @@ -669,7 +669,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 85F5B7F46D00990FBEBF0377 /* [CP] Embed Pods Frameworks */ = { @@ -678,7 +678,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh", "${BUILT_PRODUCTS_DIR}/SDWebImage-watchOS/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-watchOS/SDWebImageWebPCoder.framework", "${BUILT_PRODUCTS_DIR}/libwebp-watchOS/libwebp.framework", @@ -691,7 +691,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; A50199B809E737E017D7DF1C /* [CP] Check Pods Manifest.lock */ = { @@ -772,7 +772,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh", "${BUILT_PRODUCTS_DIR}/SDWebImage-tvOS/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-tvOS/SDWebImageWebPCoder.framework", "${BUILT_PRODUCTS_DIR}/libwebp-tvOS/libwebp.framework", @@ -785,7 +785,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index 52d8a6cb..4609fadf 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -63,6 +63,30 @@ 3257EAFC21898AED0097B271 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 3257EAF821898AED0097B271 /* SDImageGraphics.m */; }; 3257EAFD21898AED0097B271 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 3257EAF821898AED0097B271 /* SDImageGraphics.m */; }; 3257EAFE21898AED0097B271 /* SDImageGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = 3257EAF821898AED0097B271 /* SDImageGraphics.m */; }; + 325C460222339330004CAE11 /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C460022339330004CAE11 /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C460322339330004CAE11 /* SDImageAssetManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C460022339330004CAE11 /* SDImageAssetManager.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C460422339330004CAE11 /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C460122339330004CAE11 /* SDImageAssetManager.m */; }; + 325C460522339330004CAE11 /* SDImageAssetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C460122339330004CAE11 /* SDImageAssetManager.m */; }; + 325C460822339426004CAE11 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C460622339426004CAE11 /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C460922339426004CAE11 /* SDWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C460622339426004CAE11 /* SDWeakProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C460A22339426004CAE11 /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C460722339426004CAE11 /* SDWeakProxy.m */; }; + 325C460B22339426004CAE11 /* SDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C460722339426004CAE11 /* SDWeakProxy.m */; }; + 325C460E223394D8004CAE11 /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C460C223394D8004CAE11 /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C460F223394D8004CAE11 /* SDImageCachesManagerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C460C223394D8004CAE11 /* SDImageCachesManagerOperation.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C4610223394D8004CAE11 /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C460D223394D8004CAE11 /* SDImageCachesManagerOperation.m */; }; + 325C4611223394D8004CAE11 /* SDImageCachesManagerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C460D223394D8004CAE11 /* SDImageCachesManagerOperation.m */; }; + 325C4614223399F7004CAE11 /* SDImageGIFCoder+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C4612223399F7004CAE11 /* SDImageGIFCoder+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C4615223399F7004CAE11 /* SDImageGIFCoder+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C4612223399F7004CAE11 /* SDImageGIFCoder+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C461A22339B5F004CAE11 /* SDImageAPNGCoder+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C461822339B5F004CAE11 /* SDImageAPNGCoder+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C461B22339B5F004CAE11 /* SDImageAPNGCoder+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C461822339B5F004CAE11 /* SDImageAPNGCoder+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C46202233A02E004CAE11 /* UIColor+HexString.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C461E2233A02E004CAE11 /* UIColor+HexString.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C46212233A02E004CAE11 /* UIColor+HexString.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C461E2233A02E004CAE11 /* UIColor+HexString.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C46222233A02E004CAE11 /* UIColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C461F2233A02E004CAE11 /* UIColor+HexString.m */; }; + 325C46232233A02E004CAE11 /* UIColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C461F2233A02E004CAE11 /* UIColor+HexString.m */; }; + 325C46262233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C46242233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C46272233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h in Headers */ = {isa = PBXBuildFile; fileRef = 325C46242233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 325C46282233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */; }; + 325C46292233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m in Sources */ = {isa = PBXBuildFile; fileRef = 325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */; }; 327054D4206CD8B3006EA328 /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 327054D2206CD8B3006EA328 /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 327054D6206CD8B3006EA328 /* SDImageAPNGCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 327054D2206CD8B3006EA328 /* SDImageAPNGCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 327054DA206CD8B3006EA328 /* SDImageAPNGCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 327054D3206CD8B3006EA328 /* SDImageAPNGCoder.m */; }; @@ -259,6 +283,18 @@ 325312C7200F09910046BF1E /* SDWebImageTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTransition.m; sourceTree = ""; }; 3257EAF721898AED0097B271 /* SDImageGraphics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDImageGraphics.h; sourceTree = ""; }; 3257EAF821898AED0097B271 /* SDImageGraphics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDImageGraphics.m; sourceTree = ""; }; + 325C460022339330004CAE11 /* SDImageAssetManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDImageAssetManager.h; sourceTree = ""; }; + 325C460122339330004CAE11 /* SDImageAssetManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDImageAssetManager.m; sourceTree = ""; }; + 325C460622339426004CAE11 /* SDWeakProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWeakProxy.h; sourceTree = ""; }; + 325C460722339426004CAE11 /* SDWeakProxy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWeakProxy.m; sourceTree = ""; }; + 325C460C223394D8004CAE11 /* SDImageCachesManagerOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDImageCachesManagerOperation.h; sourceTree = ""; }; + 325C460D223394D8004CAE11 /* SDImageCachesManagerOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDImageCachesManagerOperation.m; sourceTree = ""; }; + 325C4612223399F7004CAE11 /* SDImageGIFCoder+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SDImageGIFCoder+Private.h"; sourceTree = ""; }; + 325C461822339B5F004CAE11 /* SDImageAPNGCoder+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SDImageAPNGCoder+Private.h"; sourceTree = ""; }; + 325C461E2233A02E004CAE11 /* UIColor+HexString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIColor+HexString.h"; sourceTree = ""; }; + 325C461F2233A02E004CAE11 /* UIColor+HexString.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIColor+HexString.m"; sourceTree = ""; }; + 325C46242233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+RoundedCorners.h"; sourceTree = ""; }; + 325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+RoundedCorners.m"; sourceTree = ""; }; 327054D2206CD8B3006EA328 /* SDImageAPNGCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImageAPNGCoder.h; sourceTree = ""; }; 327054D3206CD8B3006EA328 /* SDImageAPNGCoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageAPNGCoder.m; sourceTree = ""; }; 328BB69A2081FED200760D6C /* SDWebImageCacheKeyFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageCacheKeyFilter.h; sourceTree = ""; }; @@ -449,6 +485,18 @@ children = ( 32B5CC5E222F89C2005EB74E /* SDAsyncBlockOperation.h */, 32B5CC5F222F89C2005EB74E /* SDAsyncBlockOperation.m */, + 325C460622339426004CAE11 /* SDWeakProxy.h */, + 325C460722339426004CAE11 /* SDWeakProxy.m */, + 325C460022339330004CAE11 /* SDImageAssetManager.h */, + 325C460122339330004CAE11 /* SDImageAssetManager.m */, + 325C460C223394D8004CAE11 /* SDImageCachesManagerOperation.h */, + 325C460D223394D8004CAE11 /* SDImageCachesManagerOperation.m */, + 325C4612223399F7004CAE11 /* SDImageGIFCoder+Private.h */, + 325C461822339B5F004CAE11 /* SDImageAPNGCoder+Private.h */, + 325C461E2233A02E004CAE11 /* UIColor+HexString.h */, + 325C461F2233A02E004CAE11 /* UIColor+HexString.m */, + 325C46242233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h */, + 325C46252233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m */, ); path = Private; sourceTree = ""; @@ -655,12 +703,14 @@ 3257EAFA21898AED0097B271 /* SDImageGraphics.h in Headers */, 32D3CDD121DDE87300C4DB49 /* UIImage+MemoryCacheCost.h in Headers */, 328BB6AC2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */, + 325C46272233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h in Headers */, 321B378F2083290E00C0EA77 /* SDImageLoadersManager.h in Headers */, 329A185B1FFF5DFD008C9A2F /* UIImage+Metadata.h in Headers */, 4369C2791D9807EC007E863A /* UIView+WebCache.h in Headers */, 32F21B5320788D8C0036B1D5 /* SDWebImageDownloaderRequestModifier.h in Headers */, 321E60961F38E8ED00405457 /* SDImageIOCoder.h in Headers */, 4A2CAE041AB4BB5400B6BC39 /* SDWebImage.h in Headers */, + 325C460322339330004CAE11 /* SDImageAssetManager.h in Headers */, 327054D6206CD8B3006EA328 /* SDImageAPNGCoder.h in Headers */, 80B6DF842142B44600BCB334 /* NSButton+WebCache.h in Headers */, 43A918661D8308FE00B3925F /* SDImageCacheConfig.h in Headers */, @@ -678,12 +728,16 @@ 4A2CAE2B1AB4BB7500B6BC39 /* UIButton+WebCache.h in Headers */, 4A2CAE251AB4BB7000B6BC39 /* SDWebImagePrefetcher.h in Headers */, 328BB6CF2082581100760D6C /* SDMemoryCache.h in Headers */, + 325C460F223394D8004CAE11 /* SDImageCachesManagerOperation.h in Headers */, + 325C461B22339B5F004CAE11 /* SDImageAPNGCoder+Private.h in Headers */, 321E60881F38E8C800405457 /* SDImageCoder.h in Headers */, 4A2CAE371AB4BB7500B6BC39 /* UIView+WebCacheOperation.h in Headers */, 321B37832083290E00C0EA77 /* SDImageLoader.h in Headers */, 32484777201775F600AF9E5A /* SDAnimatedImage.h in Headers */, + 325C460922339426004CAE11 /* SDWeakProxy.h in Headers */, 80B6DF812142B43B00BCB334 /* SDAnimatedImageRep.h in Headers */, 4A2CAE2F1AB4BB7500B6BC39 /* UIImage+MultiFormat.h in Headers */, + 325C46212233A02E004CAE11 /* UIColor+HexString.h in Headers */, 325312CA200F09910046BF1E /* SDWebImageTransition.h in Headers */, 4A2CAE1A1AB4BB6400B6BC39 /* SDWebImageOperation.h in Headers */, 32484765201775F600AF9E5A /* SDAnimatedImageView+WebCache.h in Headers */, @@ -692,6 +746,7 @@ 4A2CAE1B1AB4BB6800B6BC39 /* SDWebImageDownloader.h in Headers */, 3248476B201775F600AF9E5A /* SDAnimatedImageView.h in Headers */, 32D122322080B2EB003685A3 /* SDImageCachesManager.h in Headers */, + 325C4615223399F7004CAE11 /* SDImageGIFCoder+Private.h in Headers */, 32F7C0862030719600873181 /* UIImage+Transform.h in Headers */, 321E60C01F38E91700405457 /* UIImage+ForceDecode.h in Headers */, 80B6DF7F2142B43300BCB334 /* NSImage+Compatibility.h in Headers */, @@ -713,12 +768,14 @@ 3257EAF921898AED0097B271 /* SDImageGraphics.h in Headers */, 32D3CDD021DDE87300C4DB49 /* UIImage+MemoryCacheCost.h in Headers */, 53761316155AD0D5005750A4 /* SDImageCache.h in Headers */, + 325C46262233A0A8004CAE11 /* NSBezierPath+RoundedCorners.h in Headers */, 325312C8200F09910046BF1E /* SDWebImageTransition.h in Headers */, 32C0FDE12013426C001B8F2D /* SDWebImageIndicator.h in Headers */, 321E60A21F38E8F600405457 /* SDImageGIFCoder.h in Headers */, 5D5B9142188EE8DD006D06BD /* NSData+ImageContentType.h in Headers */, 328BB6C12082581100760D6C /* SDDiskCache.h in Headers */, 53761318155AD0D5005750A4 /* SDWebImageCompat.h in Headers */, + 325C460222339330004CAE11 /* SDImageAssetManager.h in Headers */, 3290FA041FA478AF0047D20C /* SDImageFrame.h in Headers */, 80B6DF852142B44700BCB334 /* NSButton+WebCache.h in Headers */, 807A12281F89636300EC2A9B /* SDImageCodersManager.h in Headers */, @@ -736,12 +793,16 @@ 321E60BE1F38E91700405457 /* UIImage+ForceDecode.h in Headers */, 5376131E155AD0D5005750A4 /* SDWebImagePrefetcher.h in Headers */, 32F7C06F2030114C00873181 /* SDImageTransformer.h in Headers */, + 325C460E223394D8004CAE11 /* SDImageCachesManagerOperation.h in Headers */, + 325C461A22339B5F004CAE11 /* SDImageAPNGCoder+Private.h in Headers */, 321B378D2083290E00C0EA77 /* SDImageLoadersManager.h in Headers */, 32FDE8A220888789008D7530 /* SDWebImage.h in Headers */, 324DF4B4200A14DC008A84CC /* SDWebImageDefine.h in Headers */, 5376131F155AD0D5005750A4 /* UIButton+WebCache.h in Headers */, + 325C460822339426004CAE11 /* SDWeakProxy.h in Headers */, 80B6DF802142B43A00BCB334 /* SDAnimatedImageRep.h in Headers */, 327054D4206CD8B3006EA328 /* SDImageAPNGCoder.h in Headers */, + 325C46202233A02E004CAE11 /* UIColor+HexString.h in Headers */, 53761320155AD0D5005750A4 /* UIImageView+WebCache.h in Headers */, 328BB69C2081FED200760D6C /* SDWebImageCacheKeyFilter.h in Headers */, 530E49E816464C25002868E7 /* SDWebImageOperation.h in Headers */, @@ -750,6 +811,7 @@ ABBE71A718C43B4D00B75E91 /* UIImageView+HighlightedWebCache.h in Headers */, 320CAE152086F50500CFFC80 /* SDWebImageError.h in Headers */, 321B37812083290E00C0EA77 /* SDImageLoader.h in Headers */, + 325C4614223399F7004CAE11 /* SDImageGIFCoder+Private.h in Headers */, 321E60861F38E8C800405457 /* SDImageCoder.h in Headers */, 32484763201775F600AF9E5A /* SDAnimatedImageView+WebCache.h in Headers */, 80B6DF7E2142B43300BCB334 /* NSImage+Compatibility.h in Headers */, @@ -903,6 +965,7 @@ files = ( 3257EAFD21898AED0097B271 /* SDImageGraphics.m in Sources */, 3290FA0C1FA478AF0047D20C /* SDImageFrame.m in Sources */, + 325C46232233A02E004CAE11 /* UIColor+HexString.m in Sources */, 321E60C61F38E91700405457 /* UIImage+ForceDecode.m in Sources */, 328BB6A42081FED200760D6C /* SDWebImageCacheKeyFilter.m in Sources */, 4A2CAE2E1AB4BB7500B6BC39 /* UIImage+GIF.m in Sources */, @@ -929,6 +992,7 @@ 32D1222C2080B2EB003685A3 /* SDImageCachesManager.m in Sources */, 32B9B53F206ED4230026769D /* SDWebImageDownloaderConfig.m in Sources */, 43A9186D1D8308FE00B3925F /* SDImageCacheConfig.m in Sources */, + 325C46292233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m in Sources */, 3248477D201775F600AF9E5A /* SDAnimatedImageView+WebCache.m in Sources */, 321E60AA1F38E8F600405457 /* SDImageGIFCoder.m in Sources */, 321E608E1F38E8C800405457 /* SDImageCoder.m in Sources */, @@ -937,11 +1001,13 @@ 4A2CAE2A1AB4BB7500B6BC39 /* NSData+ImageContentType.m in Sources */, 4A2CAE221AB4BB7000B6BC39 /* SDWebImageManager.m in Sources */, 4A2CAE191AB4BB6400B6BC39 /* SDWebImageCompat.m in Sources */, + 325C460B22339426004CAE11 /* SDWeakProxy.m in Sources */, 321B37892083290E00C0EA77 /* SDImageLoader.m in Sources */, 32484771201775F600AF9E5A /* SDAnimatedImage.m in Sources */, 807A12301F89636300EC2A9B /* SDImageCodersManager.m in Sources */, 4A2CAE2C1AB4BB7500B6BC39 /* UIButton+WebCache.m in Sources */, 32D122262080B2EB003685A3 /* SDImageCacheDefine.m in Sources */, + 325C460522339330004CAE11 /* SDImageAssetManager.m in Sources */, 324DF4BC200A14DC008A84CC /* SDWebImageDefine.m in Sources */, 4A2CAE381AB4BB7500B6BC39 /* UIView+WebCacheOperation.m in Sources */, 32EB6D8E206D132E005CAEF6 /* SDAnimatedImageRep.m in Sources */, @@ -950,6 +1016,7 @@ 4369C2801D9807EC007E863A /* UIView+WebCache.m in Sources */, 329A18611FFF5DFD008C9A2F /* UIImage+Metadata.m in Sources */, 328BB6B22081FEE500760D6C /* SDWebImageCacheSerializer.m in Sources */, + 325C4611223394D8004CAE11 /* SDImageCachesManagerOperation.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -959,6 +1026,7 @@ files = ( 3257EAFC21898AED0097B271 /* SDImageGraphics.m in Sources */, 3290FA0A1FA478AF0047D20C /* SDImageFrame.m in Sources */, + 325C46222233A02E004CAE11 /* UIColor+HexString.m in Sources */, 321E60C41F38E91700405457 /* UIImage+ForceDecode.m in Sources */, 328BB6A22081FED200760D6C /* SDWebImageCacheKeyFilter.m in Sources */, 53761309155AD0D5005750A4 /* SDImageCache.m in Sources */, @@ -985,6 +1053,7 @@ 32D1222A2080B2EB003685A3 /* SDImageCachesManager.m in Sources */, 32B9B53D206ED4230026769D /* SDWebImageDownloaderConfig.m in Sources */, 43A9186B1D8308FE00B3925F /* SDImageCacheConfig.m in Sources */, + 325C46282233A0A8004CAE11 /* NSBezierPath+RoundedCorners.m in Sources */, 3248477B201775F600AF9E5A /* SDAnimatedImageView+WebCache.m in Sources */, 321E60A81F38E8F600405457 /* SDImageGIFCoder.m in Sources */, 321E608C1F38E8C800405457 /* SDImageCoder.m in Sources */, @@ -993,11 +1062,13 @@ 530E49EC16464C84002868E7 /* SDWebImageDownloaderOperation.m in Sources */, 53406750167780C40042B59E /* SDWebImageCompat.m in Sources */, 321B37872083290E00C0EA77 /* SDImageLoader.m in Sources */, + 325C460A22339426004CAE11 /* SDWeakProxy.m in Sources */, 3248476F201775F600AF9E5A /* SDAnimatedImage.m in Sources */, 807A122E1F89636300EC2A9B /* SDImageCodersManager.m in Sources */, A18A6CC9172DC28500419892 /* UIImage+GIF.m in Sources */, 32D122242080B2EB003685A3 /* SDImageCacheDefine.m in Sources */, 324DF4BA200A14DC008A84CC /* SDWebImageDefine.m in Sources */, + 325C460422339330004CAE11 /* SDImageAssetManager.m in Sources */, AB615306192DA24600A2D8E9 /* UIView+WebCacheOperation.m in Sources */, 32EB6D91206D132E005CAEF6 /* SDAnimatedImageRep.m in Sources */, 5D5B9145188EE8DD006D06BD /* NSData+ImageContentType.m in Sources */, @@ -1006,6 +1077,7 @@ 4369C27E1D9807EC007E863A /* UIView+WebCache.m in Sources */, 329A185F1FFF5DFD008C9A2F /* UIImage+Metadata.m in Sources */, 328BB6B02081FEE500760D6C /* SDWebImageCacheSerializer.m in Sources */, + 325C4610223394D8004CAE11 /* SDImageCachesManagerOperation.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SDWebImage/Private/NSBezierPath+RoundedCorners.h b/SDWebImage/Private/NSBezierPath+RoundedCorners.h new file mode 100644 index 00000000..224f2597 --- /dev/null +++ b/SDWebImage/Private/NSBezierPath+RoundedCorners.h @@ -0,0 +1,24 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_MAC + +#import "UIImage+Transform.h" + +@interface NSBezierPath (RoundedCorners) + +/** + Convenience way to create a bezier path with the specify rounding corners on macOS. Same as the one on `UIBezierPath`. + */ ++ (nonnull instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius; + +@end + +#endif diff --git a/SDWebImage/Private/NSBezierPath+RoundedCorners.m b/SDWebImage/Private/NSBezierPath+RoundedCorners.m new file mode 100644 index 00000000..d217bf14 --- /dev/null +++ b/SDWebImage/Private/NSBezierPath+RoundedCorners.m @@ -0,0 +1,42 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "NSBezierPath+RoundedCorners.h" + +#if SD_MAC + +@implementation NSBezierPath (RoundedCorners) + ++ (instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius { + NSBezierPath *path = [NSBezierPath bezierPath]; + + CGFloat maxCorner = MIN(NSWidth(rect), NSHeight(rect)) / 2; + + CGFloat topLeftRadius = MIN(maxCorner, (corners & SDRectCornerTopLeft) ? cornerRadius : 0); + CGFloat topRightRadius = MIN(maxCorner, (corners & SDRectCornerTopRight) ? cornerRadius : 0); + CGFloat bottomLeftRadius = MIN(maxCorner, (corners & SDRectCornerBottomLeft) ? cornerRadius : 0); + CGFloat bottomRightRadius = MIN(maxCorner, (corners & SDRectCornerBottomRight) ? cornerRadius : 0); + + NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect)); + NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); + NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect)); + NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect)); + + [path moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))]; + [path appendBezierPathWithArcFromPoint:topLeft toPoint:bottomLeft radius:topLeftRadius]; + [path appendBezierPathWithArcFromPoint:bottomLeft toPoint:bottomRight radius:bottomLeftRadius]; + [path appendBezierPathWithArcFromPoint:bottomRight toPoint:topRight radius:bottomRightRadius]; + [path appendBezierPathWithArcFromPoint:topRight toPoint:topLeft radius:topRightRadius]; + [path closePath]; + + return path; +} + +@end + +#endif diff --git a/SDWebImage/Private/SDImageAPNGCoder+Private.h b/SDWebImage/Private/SDImageAPNGCoder+Private.h new file mode 100644 index 00000000..93d53a6f --- /dev/null +++ b/SDWebImage/Private/SDImageAPNGCoder+Private.h @@ -0,0 +1,17 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDImageAPNGCoder.h" + +@interface SDImageAPNGCoder () + +- (float)sd_frameDurationAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source; +- (NSUInteger)sd_imageLoopCountWithSource:(nonnull CGImageSourceRef)source; + +@end diff --git a/SDWebImage/Private/SDImageAssetManager.h b/SDWebImage/Private/SDImageAssetManager.h new file mode 100644 index 00000000..68184187 --- /dev/null +++ b/SDWebImage/Private/SDImageAssetManager.h @@ -0,0 +1,23 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +// Apple parse the Asset Catalog compiled file(`Assets.car`) by CoreUI.framework, however it's a private framework and there are no other ways to directly get the data. So we just process the normal bundle files :) + +@interface SDImageAssetManager : NSObject + +@property (nonatomic, strong, nonnull) NSMapTable *imageTable; + ++ (nonnull instancetype)sharedAssetManager; +- (nullable NSString *)getPathForName:(nonnull NSString *)name bundle:(nonnull NSBundle *)bundle preferredScale:(nonnull CGFloat *)scale; +- (nullable UIImage *)imageForName:(nonnull NSString *)name; +- (void)storeImage:(nonnull UIImage *)image forName:(nonnull NSString *)name; + +@end diff --git a/SDWebImage/Private/SDImageAssetManager.m b/SDWebImage/Private/SDImageAssetManager.m new file mode 100644 index 00000000..1dc5503c --- /dev/null +++ b/SDWebImage/Private/SDImageAssetManager.m @@ -0,0 +1,157 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageAssetManager.h" + +static NSArray *SDBundlePreferredScales() { + static NSArray *scales; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#if SD_WATCH + CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale; +#elif SD_UIKIT + CGFloat screenScale = [UIScreen mainScreen].scale; +#elif SD_MAC + CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor; +#endif + if (screenScale <= 1) { + scales = @[@1,@2,@3]; + } else if (screenScale <= 2) { + scales = @[@2,@3,@1]; + } else { + scales = @[@3,@2,@1]; + } + }); + return scales; +} + +@implementation SDImageAssetManager { + dispatch_semaphore_t _lock; +} + ++ (instancetype)sharedAssetManager { + static dispatch_once_t onceToken; + static SDImageAssetManager *assetManager; + dispatch_once(&onceToken, ^{ + assetManager = [[SDImageAssetManager alloc] init]; + }); + return assetManager; +} + +- (instancetype)init { + self = [super init]; + if (self) { + NSPointerFunctionsOptions valueOptions; +#if SD_MAC + // Apple says that NSImage use a weak reference to value + valueOptions = NSPointerFunctionsWeakMemory; +#else + // Apple says that UIImage use a strong reference to value + valueOptions = NSPointerFunctionsStrongMemory; +#endif + _imageTable = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsCopyIn valueOptions:valueOptions]; + _lock = dispatch_semaphore_create(1); +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif + } + return self; +} + +- (void)dealloc { +#if SD_UIKIT + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#endif +} + +- (void)didReceiveMemoryWarning:(NSNotification *)notification { + SD_LOCK(_lock); + [self.imageTable removeAllObjects]; + SD_UNLOCK(_lock); +} + +- (NSString *)getPathForName:(NSString *)name bundle:(NSBundle *)bundle preferredScale:(CGFloat *)scale { + NSParameterAssert(name); + NSParameterAssert(bundle); + NSString *path; + if (name.length == 0) { + return path; + } + if ([name hasSuffix:@"/"]) { + return path; + } + NSString *extension = name.pathExtension; + if (extension.length == 0) { + // If no extension, follow Apple's doc, check PNG format + extension = @"png"; + } + name = [name stringByDeletingPathExtension]; + + CGFloat providedScale = *scale; + NSArray *scales = SDBundlePreferredScales(); + + // Check if file name contains scale + for (size_t i = 0; i < scales.count; i++) { + NSNumber *scaleValue = scales[i]; + if ([name hasSuffix:[NSString stringWithFormat:@"@%@x", scaleValue]]) { + path = [bundle pathForResource:name ofType:extension]; + if (path) { + *scale = scaleValue.doubleValue; // override + return path; + } + } + } + + // Search with provided scale first + if (providedScale != 0) { + NSString *scaledName = [name stringByAppendingFormat:@"@%@x", @(providedScale)]; + path = [bundle pathForResource:scaledName ofType:extension]; + if (path) { + return path; + } + } + + // Search with preferred scale + for (size_t i = 0; i < scales.count; i++) { + NSNumber *scaleValue = scales[i]; + if (scaleValue.doubleValue == providedScale) { + // Ignore provided scale + continue; + } + NSString *scaledName = [name stringByAppendingFormat:@"@%@x", scaleValue]; + path = [bundle pathForResource:scaledName ofType:extension]; + if (path) { + *scale = scaleValue.doubleValue; // override + return path; + } + } + + // Search without scale + path = [bundle pathForResource:name ofType:extension]; + + return path; +} + +- (UIImage *)imageForName:(NSString *)name { + NSParameterAssert(name); + UIImage *image; + SD_LOCK(_lock); + image = [self.imageTable objectForKey:name]; + SD_UNLOCK(_lock); + return image; +} + +- (void)storeImage:(UIImage *)image forName:(NSString *)name { + NSParameterAssert(image); + NSParameterAssert(name); + SD_LOCK(_lock); + [self.imageTable setObject:image forKey:name]; + SD_UNLOCK(_lock); +} + +@end diff --git a/SDWebImage/Private/SDImageCachesManagerOperation.h b/SDWebImage/Private/SDImageCachesManagerOperation.h new file mode 100644 index 00000000..fddf78c1 --- /dev/null +++ b/SDWebImage/Private/SDImageCachesManagerOperation.h @@ -0,0 +1,21 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +// This is used for operation management, but not for operation queue execute +@interface SDImageCachesManagerOperation : NSOperation + +@property (nonatomic, assign, readonly) NSUInteger pendingCount; + +- (void)beginWithTotalCount:(NSUInteger)totalCount; +- (void)completeOne; +- (void)done; + +@end diff --git a/SDWebImage/Private/SDImageCachesManagerOperation.m b/SDWebImage/Private/SDImageCachesManagerOperation.m new file mode 100644 index 00000000..67f41450 --- /dev/null +++ b/SDWebImage/Private/SDImageCachesManagerOperation.m @@ -0,0 +1,60 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCachesManagerOperation.h" + +@implementation SDImageCachesManagerOperation + +@synthesize executing = _executing; +@synthesize finished = _finished; +@synthesize cancelled = _cancelled; + +- (void)beginWithTotalCount:(NSUInteger)totalCount { + self.executing = YES; + self.finished = NO; + _pendingCount = totalCount; +} + +- (void)completeOne { + _pendingCount = _pendingCount > 0 ? _pendingCount - 1 : 0; +} + +- (void)cancel { + self.cancelled = YES; + [self reset]; +} + +- (void)done { + self.finished = YES; + self.executing = NO; + [self reset]; +} + +- (void)reset { + _pendingCount = 0; +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _finished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _executing = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (void)setCancelled:(BOOL)cancelled { + [self willChangeValueForKey:@"isCancelled"]; + _cancelled = cancelled; + [self didChangeValueForKey:@"isCancelled"]; +} + +@end diff --git a/SDWebImage/Private/SDImageGIFCoder+Private.h b/SDWebImage/Private/SDImageGIFCoder+Private.h new file mode 100644 index 00000000..769d206c --- /dev/null +++ b/SDWebImage/Private/SDImageGIFCoder+Private.h @@ -0,0 +1,16 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDImageGIFCoder.h" + +@interface SDImageGIFCoder () + +- (float)sd_frameDurationAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source; + +@end diff --git a/SDWebImage/Private/SDWeakProxy.h b/SDWebImage/Private/SDWeakProxy.h new file mode 100644 index 00000000..4fd16228 --- /dev/null +++ b/SDWebImage/Private/SDWeakProxy.h @@ -0,0 +1,19 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +@interface SDWeakProxy : NSProxy + +@property (nonatomic, weak, readonly, nullable) id target; + +- (nonnull instancetype)initWithTarget:(nonnull id)target; ++ (nonnull instancetype)proxyWithTarget:(nonnull id)target; + +@end diff --git a/SDWebImage/Private/SDWeakProxy.m b/SDWebImage/Private/SDWeakProxy.m new file mode 100644 index 00000000..19a45931 --- /dev/null +++ b/SDWebImage/Private/SDWeakProxy.m @@ -0,0 +1,79 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWeakProxy.h" + +@implementation SDWeakProxy + +- (instancetype)initWithTarget:(id)target { + _target = target; + return self; +} + ++ (instancetype)proxyWithTarget:(id)target { + return [[SDWeakProxy alloc] initWithTarget:target]; +} + +- (id)forwardingTargetForSelector:(SEL)selector { + return _target; +} + +- (void)forwardInvocation:(NSInvocation *)invocation { + void *null = NULL; + [invocation setReturnValue:&null]; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { + return [NSObject instanceMethodSignatureForSelector:@selector(init)]; +} + +- (BOOL)respondsToSelector:(SEL)aSelector { + return [_target respondsToSelector:aSelector]; +} + +- (BOOL)isEqual:(id)object { + return [_target isEqual:object]; +} + +- (NSUInteger)hash { + return [_target hash]; +} + +- (Class)superclass { + return [_target superclass]; +} + +- (Class)class { + return [_target class]; +} + +- (BOOL)isKindOfClass:(Class)aClass { + return [_target isKindOfClass:aClass]; +} + +- (BOOL)isMemberOfClass:(Class)aClass { + return [_target isMemberOfClass:aClass]; +} + +- (BOOL)conformsToProtocol:(Protocol *)aProtocol { + return [_target conformsToProtocol:aProtocol]; +} + +- (BOOL)isProxy { + return YES; +} + +- (NSString *)description { + return [_target description]; +} + +- (NSString *)debugDescription { + return [_target debugDescription]; +} + +@end diff --git a/SDWebImage/Private/UIColor+HexString.h b/SDWebImage/Private/UIColor+HexString.h new file mode 100644 index 00000000..2a8a3d80 --- /dev/null +++ b/SDWebImage/Private/UIColor+HexString.h @@ -0,0 +1,18 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +@interface UIColor (HexString) + +/** + Convenience way to get hex string from color. The output should always be 32-bit RGBA hex string like `#00000000`. + */ +@property (nonatomic, copy, readonly, nonnull) NSString *sd_hexString; + +@end diff --git a/SDWebImage/Private/UIColor+HexString.m b/SDWebImage/Private/UIColor+HexString.m new file mode 100644 index 00000000..aebb6e3b --- /dev/null +++ b/SDWebImage/Private/UIColor+HexString.m @@ -0,0 +1,42 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIColor+HexString.h" + +@implementation UIColor (HexString) + +- (NSString *)sd_hexString { + CGFloat red, green, blue, alpha; +#if SD_UIKIT + if (![self getRed:&red green:&green blue:&blue alpha:&alpha]) { + [self getWhite:&red alpha:&alpha]; + green = red; + blue = red; + } +#else + @try { + [self getRed:&red green:&green blue:&blue alpha:&alpha]; + } + @catch (NSException *exception) { + [self getWhite:&red alpha:&alpha]; + green = red; + blue = red; + } +#endif + + red = roundf(red * 255.f); + green = roundf(green * 255.f); + blue = roundf(blue * 255.f); + alpha = roundf(alpha * 255.f); + + uint hex = ((uint)alpha << 24) | ((uint)red << 16) | ((uint)green << 8) | ((uint)blue); + + return [NSString stringWithFormat:@"#%08x", hex]; +} + +@end diff --git a/SDWebImage/SDAnimatedImage.m b/SDWebImage/SDAnimatedImage.m index 6b779289..9fbd13e3 100644 --- a/SDWebImage/SDAnimatedImage.m +++ b/SDWebImage/SDAnimatedImage.m @@ -12,6 +12,7 @@ #import "SDImageCodersManager.h" #import "SDImageFrame.h" #import "UIImage+MemoryCacheCost.h" +#import "SDImageAssetManager.h" #import "objc/runtime.h" static CGFloat SDImageScaleFromPath(NSString *string) { @@ -29,169 +30,6 @@ static CGFloat SDImageScaleFromPath(NSString *string) { return scale; } -static NSArray *SDBundlePreferredScales() { - static NSArray *scales; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ -#if SD_WATCH - CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale; -#elif SD_UIKIT - CGFloat screenScale = [UIScreen mainScreen].scale; -#elif SD_MAC - CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor; -#endif - if (screenScale <= 1) { - scales = @[@1,@2,@3]; - } else if (screenScale <= 2) { - scales = @[@2,@3,@1]; - } else { - scales = @[@3,@2,@1]; - } - }); - return scales; -} - -#pragma mark - UIImage cache for bundle - -// Apple parse the Asset Catalog compiled file(`Assets.car`) by CoreUI.framework, however it's a private framework and there are no other ways to directly get the data. So we just process the normal bundle files :) - -@interface SDImageAssetManager : NSObject { - dispatch_semaphore_t _lock; -} - -@property (nonatomic, strong) NSMapTable *imageTable; - -+ (instancetype)sharedAssetManager; -- (nullable NSString *)getPathForName:(nonnull NSString *)name bundle:(nonnull NSBundle *)bundle preferredScale:(CGFloat *)scale; -- (nullable UIImage *)imageForName:(nonnull NSString *)name; -- (void)storeImage:(nonnull UIImage *)image forName:(nonnull NSString *)name; - -@end - -@implementation SDImageAssetManager - -+ (instancetype)sharedAssetManager { - static dispatch_once_t onceToken; - static SDImageAssetManager *assetManager; - dispatch_once(&onceToken, ^{ - assetManager = [[SDImageAssetManager alloc] init]; - }); - return assetManager; -} - -- (instancetype)init { - self = [super init]; - if (self) { - NSPointerFunctionsOptions valueOptions; -#if SD_MAC - // Apple says that NSImage use a weak reference to value - valueOptions = NSPointerFunctionsWeakMemory; -#else - // Apple says that UIImage use a strong reference to value - valueOptions = NSPointerFunctionsStrongMemory; -#endif - _imageTable = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsCopyIn valueOptions:valueOptions]; - _lock = dispatch_semaphore_create(1); -#if SD_UIKIT - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; -#endif - } - return self; -} - -- (void)dealloc { -#if SD_UIKIT - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; -#endif -} - -- (void)didReceiveMemoryWarning:(NSNotification *)notification { - SD_LOCK(_lock); - [self.imageTable removeAllObjects]; - SD_UNLOCK(_lock); -} - -- (NSString *)getPathForName:(NSString *)name bundle:(NSBundle *)bundle preferredScale:(CGFloat *)scale { - NSParameterAssert(name); - NSParameterAssert(bundle); - NSString *path; - if (name.length == 0) { - return path; - } - if ([name hasSuffix:@"/"]) { - return path; - } - NSString *extension = name.pathExtension; - if (extension.length == 0) { - // If no extension, follow Apple's doc, check PNG format - extension = @"png"; - } - name = [name stringByDeletingPathExtension]; - - CGFloat providedScale = *scale; - NSArray *scales = SDBundlePreferredScales(); - - // Check if file name contains scale - for (size_t i = 0; i < scales.count; i++) { - NSNumber *scaleValue = scales[i]; - if ([name hasSuffix:[NSString stringWithFormat:@"@%@x", scaleValue]]) { - path = [bundle pathForResource:name ofType:extension]; - if (path) { - *scale = scaleValue.doubleValue; // override - return path; - } - } - } - - // Search with provided scale first - if (providedScale != 0) { - NSString *scaledName = [name stringByAppendingFormat:@"@%@x", @(providedScale)]; - path = [bundle pathForResource:scaledName ofType:extension]; - if (path) { - return path; - } - } - - // Search with preferred scale - for (size_t i = 0; i < scales.count; i++) { - NSNumber *scaleValue = scales[i]; - if (scaleValue.doubleValue == providedScale) { - // Ignore provided scale - continue; - } - NSString *scaledName = [name stringByAppendingFormat:@"@%@x", scaleValue]; - path = [bundle pathForResource:scaledName ofType:extension]; - if (path) { - *scale = scaleValue.doubleValue; // override - return path; - } - } - - // Search without scale - path = [bundle pathForResource:name ofType:extension]; - - return path; -} - -- (UIImage *)imageForName:(NSString *)name { - NSParameterAssert(name); - UIImage *image; - SD_LOCK(_lock); - image = [self.imageTable objectForKey:name]; - SD_UNLOCK(_lock); - return image; -} - -- (void)storeImage:(UIImage *)image forName:(NSString *)name { - NSParameterAssert(image); - NSParameterAssert(name); - SD_LOCK(_lock); - [self.imageTable setObject:image forKey:name]; - SD_UNLOCK(_lock); -} - -@end - @interface SDAnimatedImage () @property (nonatomic, strong) id coder; diff --git a/SDWebImage/SDAnimatedImageRep.m b/SDWebImage/SDAnimatedImageRep.m index 106dfc1d..06943d7d 100644 --- a/SDWebImage/SDAnimatedImageRep.m +++ b/SDWebImage/SDAnimatedImageRep.m @@ -10,21 +10,8 @@ #if SD_MAC -#import "SDImageGIFCoder.h" -#import "SDImageAPNGCoder.h" - -@interface SDImageGIFCoder () - -- (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source; - -@end - -@interface SDImageAPNGCoder () - -- (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source; -- (NSUInteger)sd_imageLoopCountWithSource:(CGImageSourceRef)source; - -@end +#import "SDImageGIFCoder+Private.h" +#import "SDImageAPNGCoder+Private.h" @interface SDAnimatedImageRep () diff --git a/SDWebImage/SDAnimatedImageView.m b/SDWebImage/SDAnimatedImageView.m index 7810744f..42c731d2 100644 --- a/SDWebImage/SDAnimatedImageView.m +++ b/SDWebImage/SDAnimatedImageView.m @@ -12,6 +12,7 @@ #import "UIImage+Metadata.h" #import "NSImage+Compatibility.h" +#import "SDWeakProxy.h" #import #import @@ -38,85 +39,6 @@ static NSUInteger SDDeviceFreeMemory() { return vm_stat.free_count * page_size; } -@interface SDWeakProxy : NSProxy - -@property (nonatomic, weak, readonly) id target; - -- (instancetype)initWithTarget:(id)target; -+ (instancetype)proxyWithTarget:(id)target; - -@end - -@implementation SDWeakProxy - -- (instancetype)initWithTarget:(id)target { - _target = target; - return self; -} - -+ (instancetype)proxyWithTarget:(id)target { - return [[SDWeakProxy alloc] initWithTarget:target]; -} - -- (id)forwardingTargetForSelector:(SEL)selector { - return _target; -} - -- (void)forwardInvocation:(NSInvocation *)invocation { - void *null = NULL; - [invocation setReturnValue:&null]; -} - -- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { - return [NSObject instanceMethodSignatureForSelector:@selector(init)]; -} - -- (BOOL)respondsToSelector:(SEL)aSelector { - return [_target respondsToSelector:aSelector]; -} - -- (BOOL)isEqual:(id)object { - return [_target isEqual:object]; -} - -- (NSUInteger)hash { - return [_target hash]; -} - -- (Class)superclass { - return [_target superclass]; -} - -- (Class)class { - return [_target class]; -} - -- (BOOL)isKindOfClass:(Class)aClass { - return [_target isKindOfClass:aClass]; -} - -- (BOOL)isMemberOfClass:(Class)aClass { - return [_target isMemberOfClass:aClass]; -} - -- (BOOL)conformsToProtocol:(Protocol *)aProtocol { - return [_target conformsToProtocol:aProtocol]; -} - -- (BOOL)isProxy { - return YES; -} - -- (NSString *)description { - return [_target description]; -} - -- (NSString *)debugDescription { - return [_target debugDescription]; -} - -@end - @interface SDAnimatedImageView () @property (nonatomic, strong, readwrite) UIImage *currentFrame; diff --git a/SDWebImage/SDImageCachesManager.m b/SDWebImage/SDImageCachesManager.m index 1da509f0..1700737e 100644 --- a/SDWebImage/SDImageCachesManager.m +++ b/SDWebImage/SDImageCachesManager.m @@ -7,68 +7,7 @@ */ #import "SDImageCachesManager.h" - -// This is used for operation management, but not for operation queue execute -@interface SDImageCachesManagerOperation : NSOperation - -@property (nonatomic, assign, readonly) NSUInteger pendingCount; - -- (void)beginWithTotalCount:(NSUInteger)totalCount; -- (void)completeOne; -- (void)done; - -@end - -@implementation SDImageCachesManagerOperation - -@synthesize executing = _executing; -@synthesize finished = _finished; -@synthesize cancelled = _cancelled; - -- (void)beginWithTotalCount:(NSUInteger)totalCount { - self.executing = YES; - self.finished = NO; - _pendingCount = totalCount; -} - -- (void)completeOne { - _pendingCount = _pendingCount > 0 ? _pendingCount - 1 : 0; -} - -- (void)cancel { - self.cancelled = YES; - [self reset]; -} - -- (void)done { - self.finished = YES; - self.executing = NO; - [self reset]; -} - -- (void)reset { - _pendingCount = 0; -} - -- (void)setFinished:(BOOL)finished { - [self willChangeValueForKey:@"isFinished"]; - _finished = finished; - [self didChangeValueForKey:@"isFinished"]; -} - -- (void)setExecuting:(BOOL)executing { - [self willChangeValueForKey:@"isExecuting"]; - _executing = executing; - [self didChangeValueForKey:@"isExecuting"]; -} - -- (void)setCancelled:(BOOL)cancelled { - [self willChangeValueForKey:@"isCancelled"]; - _cancelled = cancelled; - [self didChangeValueForKey:@"isCancelled"]; -} - -@end +#import "SDImageCachesManagerOperation.h" @implementation SDImageCachesManager diff --git a/SDWebImage/SDImageTransformer.m b/SDWebImage/SDImageTransformer.m index 0b0b58d7..9cbb0015 100644 --- a/SDWebImage/SDImageTransformer.m +++ b/SDWebImage/SDImageTransformer.m @@ -7,6 +7,7 @@ */ #import "SDImageTransformer.h" +#import "UIColor+HexString.h" #if SD_UIKIT || SD_MAC #import #endif @@ -21,48 +22,6 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * return [[key stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey]; } -@interface UIColor (HexString) - -/** - Convenience way to get hex string from color. The output should always be 32-bit RGBA hex string like `#00000000`. - */ -@property (nonatomic, copy, readonly, nonnull) NSString *sd_hexString; - -@end - -@implementation UIColor (HexString) - -- (NSString *)sd_hexString { - CGFloat red, green, blue, alpha; -#if SD_UIKIT - if (![self getRed:&red green:&green blue:&blue alpha:&alpha]) { - [self getWhite:&red alpha:&alpha]; - green = red; - blue = red; - } -#else - @try { - [self getRed:&red green:&green blue:&blue alpha:&alpha]; - } - @catch (NSException *exception) { - [self getWhite:&red alpha:&alpha]; - green = red; - blue = red; - } -#endif - - red = roundf(red * 255.f); - green = roundf(green * 255.f); - blue = roundf(blue * 255.f); - alpha = roundf(alpha * 255.f); - - uint hex = ((uint)alpha << 24) | ((uint)red << 16) | ((uint)green << 8) | ((uint)blue); - - return [NSString stringWithFormat:@"#%08x", hex]; -} - -@end - @interface SDImagePipelineTransformer () @property (nonatomic, copy, readwrite, nonnull) NSArray> *transformers; diff --git a/SDWebImage/UIImage+Transform.m b/SDWebImage/UIImage+Transform.m index 6d844ec9..acf86fb1 100644 --- a/SDWebImage/UIImage+Transform.m +++ b/SDWebImage/UIImage+Transform.m @@ -9,6 +9,7 @@ #import "UIImage+Transform.h" #import "NSImage+Compatibility.h" #import "SDImageGraphics.h" +#import "NSBezierPath+RoundedCorners.h" #import #if SD_UIKIT || SD_MAC #import @@ -162,46 +163,6 @@ static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitma return [UIColor colorWithRed:r green:g blue:b alpha:a]; } -#if SD_MAC -@interface NSBezierPath (RoundedCorners) - -/** - Convenience way to create a bezier path with the specify rounding corners on macOS. Same as the one on `UIBezierPath`. - */ -+ (nonnull instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius; - -@end - -@implementation NSBezierPath (RoundedCorners) - -+ (instancetype)sd_bezierPathWithRoundedRect:(NSRect)rect byRoundingCorners:(SDRectCorner)corners cornerRadius:(CGFloat)cornerRadius { - NSBezierPath *path = [NSBezierPath bezierPath]; - - CGFloat maxCorner = MIN(NSWidth(rect), NSHeight(rect)) / 2; - - CGFloat topLeftRadius = MIN(maxCorner, (corners & SDRectCornerTopLeft) ? cornerRadius : 0); - CGFloat topRightRadius = MIN(maxCorner, (corners & SDRectCornerTopRight) ? cornerRadius : 0); - CGFloat bottomLeftRadius = MIN(maxCorner, (corners & SDRectCornerBottomLeft) ? cornerRadius : 0); - CGFloat bottomRightRadius = MIN(maxCorner, (corners & SDRectCornerBottomRight) ? cornerRadius : 0); - - NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect)); - NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); - NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect)); - NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect)); - - [path moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))]; - [path appendBezierPathWithArcFromPoint:topLeft toPoint:bottomLeft radius:topLeftRadius]; - [path appendBezierPathWithArcFromPoint:bottomLeft toPoint:bottomRight radius:bottomLeftRadius]; - [path appendBezierPathWithArcFromPoint:bottomRight toPoint:topRight radius:bottomRightRadius]; - [path appendBezierPathWithArcFromPoint:topRight toPoint:topLeft radius:topRightRadius]; - [path closePath]; - - return path; -} - -@end -#endif - @implementation UIImage (Transform) - (void)sd_drawInRect:(CGRect)rect withScaleMode:(SDImageScaleMode)scaleMode clipsToBounds:(BOOL)clips { diff --git a/Tests/SDWebImage Tests.xcodeproj/project.pbxproj b/Tests/SDWebImage Tests.xcodeproj/project.pbxproj index fb70541b..30a05d56 100644 --- a/Tests/SDWebImage Tests.xcodeproj/project.pbxproj +++ b/Tests/SDWebImage Tests.xcodeproj/project.pbxproj @@ -408,7 +408,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh", "${BUILT_PRODUCTS_DIR}/Expecta-macOS/Expecta.framework", "${BUILT_PRODUCTS_DIR}/KVOController-macOS/KVOController.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage-macOS/SDWebImage.framework", @@ -421,7 +421,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; A07943B19E185DC24535F340 /* [CP] Embed Pods Frameworks */ = { @@ -430,7 +430,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh", "${BUILT_PRODUCTS_DIR}/Expecta-iOS/Expecta.framework", "${BUILT_PRODUCTS_DIR}/KVOController-iOS/KVOController.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage-iOS/SDWebImage.framework", @@ -443,7 +443,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */