Authored by Bogdan Poplauschi

Merge branch '4.x' into gif

# Conflicts:
#	SDWebImage/MKAnnotationView+WebCache.h
#	SDWebImage/MKAnnotationView+WebCache.m
#	SDWebImage/SDImageCache.h
#	SDWebImage/SDImageCache.m
#	SDWebImage/SDWebImageManager.h
#	SDWebImage/SDWebImageManager.m
#	SDWebImage/UIButton+WebCache.h
#	SDWebImage/UIButton+WebCache.m
#	SDWebImage/UIImageView+HighlightedWebCache.h
#	SDWebImage/UIImageView+HighlightedWebCache.m
#	SDWebImage/UIImageView+WebCache.h
#	SDWebImage/UIImageView+WebCache.m
  1 +## [3.8.1 Patch release for 3.8.0 on Jun 7th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.1)
  2 +
  3 +#### Fixes:
  4 +
  5 +- SDWebImage 3.8.0 get wrong image #1589 - the issue was caused by the changes in 3.8.0 (Removed the URL query params from the filename (key) fb0cdb6d 1bf62d4 #1584 - fixes #1433 #1553 #1583 #1585) - Reverted.
  6 +- Note: The solution for those issues (i.e. #1433 #1553) is to set the `SDWebImageManager` `cacheKeyFilter` block and do their own calculations there.
  7 +
1 ## [3.8.0 Minor release - Replaces NSURLConnection (deprecated) with NSURLSession - on Jun 6th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.0) 8 ## [3.8.0 Minor release - Replaces NSURLConnection (deprecated) with NSURLSession - on Jun 6th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.0)
2 9
3 #### Infrastructure: 10 #### Infrastructure:
@@ -11,7 +18,7 @@ @@ -11,7 +18,7 @@
11 18
12 #### Fixes: 19 #### Fixes:
13 20
14 -- Removed the URL query params from the filename (key) fb0cdb6d 1bf62d4 #1584 - fixes #1433 #1533 #1583 #1585 21 +- Removed the URL query params from the filename (key) fb0cdb6d 1bf62d4 #1584 - fixes #1433 #1553 #1583 #1585
15 - Fixed the WebP build with the official 1.0.0 CocoaPods release f1a471e - fixes #1444 22 - Fixed the WebP build with the official 1.0.0 CocoaPods release f1a471e - fixes #1444
16 - Updated doc: `removeImageForKey:` not synchronous e6e5c51 - fixes #1379 #1415 23 - Updated doc: `removeImageForKey:` not synchronous e6e5c51 - fixes #1379 #1415
17 24
1 Pod::Spec.new do |s| 1 Pod::Spec.new do |s|
2 s.name = 'SDWebImage' 2 s.name = 'SDWebImage'
3 - s.version = '3.8.0' 3 + s.version = '3.8.1'
4 s.ios.deployment_target = '7.0' 4 s.ios.deployment_target = '7.0'
5 s.tvos.deployment_target = '9.0' 5 s.tvos.deployment_target = '9.0'
6 s.license = 'MIT' 6 s.license = 'MIT'
@@ -1423,6 +1423,7 @@ @@ -1423,6 +1423,7 @@
1423 isa = XCBuildConfiguration; 1423 isa = XCBuildConfiguration;
1424 buildSettings = { 1424 buildSettings = {
1425 ALWAYS_SEARCH_USER_PATHS = NO; 1425 ALWAYS_SEARCH_USER_PATHS = NO;
  1426 + CLANG_ANALYZER_NONNULL = YES;
1426 CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1427 CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
1427 CLANG_CXX_LIBRARY = "libc++"; 1428 CLANG_CXX_LIBRARY = "libc++";
1428 CLANG_ENABLE_MODULES = YES; 1429 CLANG_ENABLE_MODULES = YES;
@@ -1483,6 +1484,7 @@ @@ -1483,6 +1484,7 @@
1483 isa = XCBuildConfiguration; 1484 isa = XCBuildConfiguration;
1484 buildSettings = { 1485 buildSettings = {
1485 ALWAYS_SEARCH_USER_PATHS = NO; 1486 ALWAYS_SEARCH_USER_PATHS = NO;
  1487 + CLANG_ANALYZER_NONNULL = YES;
1486 CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1488 CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
1487 CLANG_CXX_LIBRARY = "libc++"; 1489 CLANG_CXX_LIBRARY = "libc++";
1488 CLANG_ENABLE_MODULES = YES; 1490 CLANG_ENABLE_MODULES = YES;
@@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
28 * Note that because of the limitations of categories this property can get out of sync 28 * Note that because of the limitations of categories this property can get out of sync
29 * if you use setImage: directly. 29 * if you use setImage: directly.
30 */ 30 */
31 -- (NSURL *)sd_imageURL; 31 +- (nullable NSURL *)sd_imageURL;
32 32
33 /** 33 /**
34 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 34 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 * 36 *
37 * @param url The url for the image. 37 * @param url The url for the image.
38 */ 38 */
39 -- (void)sd_setImageWithURL:(NSURL *)url; 39 +- (void)sd_setImageWithURL:(nullable NSURL *)url;
40 40
41 /** 41 /**
42 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 42 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
@@ -46,7 +46,8 @@ @@ -46,7 +46,8 @@
46 * @param url The url for the image. 46 * @param url The url for the image.
47 * @param placeholder The image to be set initially, until the image request finishes. 47 * @param placeholder The image to be set initially, until the image request finishes.
48 */ 48 */
49 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 49 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  50 + placeholderImage:(nullable UIImage *)placeholder;
50 51
51 /** 52 /**
52 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 53 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
@@ -57,7 +58,9 @@ @@ -57,7 +58,9 @@
57 * @param placeholder The image to be set initially, until the image request finishes. 58 * @param placeholder The image to be set initially, until the image request finishes.
58 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 59 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
59 */ 60 */
60 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 61 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  62 + placeholderImage:(nullable UIImage *)placeholder
  63 + options:(SDWebImageOptions)options;
61 64
62 /** 65 /**
63 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 66 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
@@ -70,7 +73,8 @@ @@ -70,7 +73,8 @@
70 * indicating if the image was retrieved from the local cache or from the network. 73 * indicating if the image was retrieved from the local cache or from the network.
71 * The fourth parameter is the original image url. 74 * The fourth parameter is the original image url.
72 */ 75 */
73 -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; 76 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  77 + completed:(nullable SDExternalCompletionBlock)completedBlock;
74 78
75 /** 79 /**
76 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 80 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
@@ -85,7 +89,9 @@ @@ -85,7 +89,9 @@
85 * indicating if the image was retrieved from the local cache or from the network. 89 * indicating if the image was retrieved from the local cache or from the network.
86 * The fourth parameter is the original image url. 90 * The fourth parameter is the original image url.
87 */ 91 */
88 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; 92 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  93 + placeholderImage:(nullable UIImage *)placeholder
  94 + completed:(nullable SDExternalCompletionBlock)completedBlock;
89 95
90 /** 96 /**
91 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 97 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
@@ -101,7 +107,10 @@ @@ -101,7 +107,10 @@
101 * indicating if the image was retrieved from the local cache or from the network. 107 * indicating if the image was retrieved from the local cache or from the network.
102 * The fourth parameter is the original image url. 108 * The fourth parameter is the original image url.
103 */ 109 */
104 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; 110 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  111 + placeholderImage:(nullable UIImage *)placeholder
  112 + options:(SDWebImageOptions)options
  113 + completed:(nullable SDExternalCompletionBlock)completedBlock;
105 114
106 /** 115 /**
107 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 116 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
@@ -118,7 +127,11 @@ @@ -118,7 +127,11 @@
118 * indicating if the image was retrieved from the local cache or from the network. 127 * indicating if the image was retrieved from the local cache or from the network.
119 * The fourth parameter is the original image url. 128 * The fourth parameter is the original image url.
120 */ 129 */
121 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; 130 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  131 + placeholderImage:(nullable UIImage *)placeholder
  132 + options:(SDWebImageOptions)options
  133 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  134 + completed:(nullable SDExternalCompletionBlock)completedBlock;
122 135
123 /** 136 /**
124 * Cancel the image load 137 * Cancel the image load
@@ -19,35 +19,39 @@ static char imageURLKey; @@ -19,35 +19,39 @@ static char imageURLKey;
19 19
20 @implementation FLAnimatedImageView (WebCache) 20 @implementation FLAnimatedImageView (WebCache)
21 21
22 -- (NSURL *)sd_imageURL { 22 +- (nullable NSURL *)sd_imageURL {
23 return objc_getAssociatedObject(self, &imageURLKey); 23 return objc_getAssociatedObject(self, &imageURLKey);
24 } 24 }
25 25
26 -- (void)sd_setImageWithURL:(NSURL *)url { 26 +- (void)sd_setImageWithURL:(nullable NSURL *)url {
27 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; 27 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
28 } 28 }
29 29
30 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { 30 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
31 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; 31 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
32 } 32 }
33 33
34 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 34 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
35 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; 35 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
36 } 36 }
37 37
38 -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { 38 +- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
39 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; 39 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
40 } 40 }
41 41
42 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { 42 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
43 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; 43 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
44 } 44 }
45 45
46 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { 46 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {
47 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; 47 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
48 } 48 }
49 49
50 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { 50 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  51 + placeholderImage:(nullable UIImage *)placeholder
  52 + options:(SDWebImageOptions)options
  53 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  54 + completed:(nullable SDExternalCompletionBlock)completedBlock {
51 [self sd_cancelCurrentImageLoad]; 55 [self sd_cancelCurrentImageLoad];
52 objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 56 objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
53 57
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 * Note that because of the limitations of categories this property can get out of sync 20 * Note that because of the limitations of categories this property can get out of sync
21 * if you use setImage: directly. 21 * if you use setImage: directly.
22 */ 22 */
23 -- (NSURL *)sd_imageURL; 23 +- (nullable NSURL *)sd_imageURL;
24 24
25 /** 25 /**
26 * Set the imageView `image` with an `url`. 26 * Set the imageView `image` with an `url`.
@@ -29,7 +29,7 @@ @@ -29,7 +29,7 @@
29 * 29 *
30 * @param url The url for the image. 30 * @param url The url for the image.
31 */ 31 */
32 -- (void)sd_setImageWithURL:(NSURL *)url; 32 +- (void)sd_setImageWithURL:(nullable NSURL *)url;
33 33
34 /** 34 /**
35 * Set the imageView `image` with an `url` and a placeholder. 35 * Set the imageView `image` with an `url` and a placeholder.
@@ -40,7 +40,8 @@ @@ -40,7 +40,8 @@
40 * @param placeholder The image to be set initially, until the image request finishes. 40 * @param placeholder The image to be set initially, until the image request finishes.
41 * @see sd_setImageWithURL:placeholderImage:options: 41 * @see sd_setImageWithURL:placeholderImage:options:
42 */ 42 */
43 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 43 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  44 + placeholderImage:(nullable UIImage *)placeholder;
44 45
45 /** 46 /**
46 * Set the imageView `image` with an `url`, placeholder and custom options. 47 * Set the imageView `image` with an `url`, placeholder and custom options.
@@ -52,7 +53,9 @@ @@ -52,7 +53,9 @@
52 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 53 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
53 */ 54 */
54 55
55 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 56 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  57 + placeholderImage:(nullable UIImage *)placeholder
  58 + options:(SDWebImageOptions)options;
56 59
57 /** 60 /**
58 * Set the imageView `image` with an `url`. 61 * Set the imageView `image` with an `url`.
@@ -66,7 +69,8 @@ @@ -66,7 +69,8 @@
66 * indicating if the image was retrieved from the local cache or from the network. 69 * indicating if the image was retrieved from the local cache or from the network.
67 * The fourth parameter is the original image url. 70 * The fourth parameter is the original image url.
68 */ 71 */
69 -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; 72 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  73 + completed:(nullable SDExternalCompletionBlock)completedBlock;
70 74
71 /** 75 /**
72 * Set the imageView `image` with an `url`, placeholder. 76 * Set the imageView `image` with an `url`, placeholder.
@@ -81,7 +85,9 @@ @@ -81,7 +85,9 @@
81 * indicating if the image was retrieved from the local cache or from the network. 85 * indicating if the image was retrieved from the local cache or from the network.
82 * The fourth parameter is the original image url. 86 * The fourth parameter is the original image url.
83 */ 87 */
84 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; 88 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  89 + placeholderImage:(nullable UIImage *)placeholder
  90 + completed:(nullable SDExternalCompletionBlock)completedBlock;
85 91
86 /** 92 /**
87 * Set the imageView `image` with an `url`, placeholder and custom options. 93 * Set the imageView `image` with an `url`, placeholder and custom options.
@@ -97,7 +103,10 @@ @@ -97,7 +103,10 @@
97 * indicating if the image was retrieved from the local cache or from the network. 103 * indicating if the image was retrieved from the local cache or from the network.
98 * The fourth parameter is the original image url. 104 * The fourth parameter is the original image url.
99 */ 105 */
100 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; 106 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  107 + placeholderImage:(nullable UIImage *)placeholder
  108 + options:(SDWebImageOptions)options
  109 + completed:(nullable SDExternalCompletionBlock)completedBlock;
101 110
102 /** 111 /**
103 * Cancel the current download 112 * Cancel the current download
@@ -14,31 +14,34 @@ static char imageURLKey; @@ -14,31 +14,34 @@ static char imageURLKey;
14 14
15 @implementation MKAnnotationView (WebCache) 15 @implementation MKAnnotationView (WebCache)
16 16
17 -- (NSURL *)sd_imageURL { 17 +- (nullable NSURL *)sd_imageURL {
18 return objc_getAssociatedObject(self, &imageURLKey); 18 return objc_getAssociatedObject(self, &imageURLKey);
19 } 19 }
20 20
21 -- (void)sd_setImageWithURL:(NSURL *)url { 21 +- (void)sd_setImageWithURL:(nullable NSURL *)url {
22 [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; 22 [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
23 } 23 }
24 24
25 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { 25 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
26 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; 26 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil];
27 } 27 }
28 28
29 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 29 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
30 [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; 30 [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil];
31 } 31 }
32 32
33 -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { 33 +- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
34 [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock]; 34 [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock];
35 } 35 }
36 36
37 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { 37 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
38 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock]; 38 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock];
39 } 39 }
40 40
41 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { 41 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  42 + placeholderImage:(nullable UIImage *)placeholder
  43 + options:(SDWebImageOptions)options
  44 + completed:(nullable SDExternalCompletionBlock)completedBlock {
42 [self sd_cancelCurrentImageLoad]; 45 [self sd_cancelCurrentImageLoad];
43 46
44 objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 47 objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
@@ -18,6 +18,6 @@ @@ -18,6 +18,6 @@
18 * 18 *
19 * @return the content type as string (i.e. image/jpeg, image/gif) 19 * @return the content type as string (i.e. image/jpeg, image/gif)
20 */ 20 */
21 -+ (NSString *)sd_contentTypeForImageData:(NSData *)data; 21 ++ (nullable NSString *)sd_contentTypeForImageData:(nullable NSData *)data;
22 22
23 @end 23 @end
@@ -12,7 +12,11 @@ @@ -12,7 +12,11 @@
12 12
13 @implementation NSData (ImageContentType) 13 @implementation NSData (ImageContentType)
14 14
15 -+ (NSString *)sd_contentTypeForImageData:(NSData *)data { 15 ++ (nullable NSString *)sd_contentTypeForImageData:(nullable NSData *)data {
  16 + if (!data) {
  17 + return nil;
  18 + }
  19 +
16 uint8_t c; 20 uint8_t c;
17 [data getBytes:&c length:1]; 21 [data getBytes:&c length:1];
18 switch (c) { 22 switch (c) {
@@ -24,7 +24,7 @@ typedef NS_ENUM(NSInteger, SDImageCacheType) { @@ -24,7 +24,7 @@ typedef NS_ENUM(NSInteger, SDImageCacheType) {
24 SDImageCacheTypeMemory 24 SDImageCacheTypeMemory
25 }; 25 };
26 26
27 -typedef void(^SDCacheQueryCompletedBlock)(UIImage *image, NSData *data, SDImageCacheType cacheType); 27 +typedef void(^SDCacheQueryCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType);
28 28
29 typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache); 29 typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
30 30
@@ -77,14 +77,14 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -77,14 +77,14 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
77 * 77 *
78 * @return SDImageCache global instance 78 * @return SDImageCache global instance
79 */ 79 */
80 -+ (SDImageCache *)sharedImageCache; 80 ++ (nonnull SDImageCache *)sharedImageCache;
81 81
82 /** 82 /**
83 * Init a new cache store with a specific namespace 83 * Init a new cache store with a specific namespace
84 * 84 *
85 * @param ns The namespace to use for this cache store 85 * @param ns The namespace to use for this cache store
86 */ 86 */
87 -- (instancetype)initWithNamespace:(NSString *)ns; 87 +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns;
88 88
89 /** 89 /**
90 * Init a new cache store with a specific namespace and directory 90 * Init a new cache store with a specific namespace and directory
@@ -92,10 +92,10 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -92,10 +92,10 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
92 * @param ns The namespace to use for this cache store 92 * @param ns The namespace to use for this cache store
93 * @param directory Directory to cache disk images in 93 * @param directory Directory to cache disk images in
94 */ 94 */
95 -- (instancetype)initWithNamespace:(NSString *)ns  
96 - diskCacheDirectory:(NSString *)directory NS_DESIGNATED_INITIALIZER; 95 +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns
  96 + diskCacheDirectory:(nonnull NSString *)directory NS_DESIGNATED_INITIALIZER;
97 97
98 --(NSString *)makeDiskCachePath:(NSString*)fullNamespace; 98 +- (nullable NSString *)makeDiskCachePath:(nonnull NSString*)fullNamespace;
99 99
100 /** 100 /**
101 * Add a read-only cache path to search for images pre-cached by SDImageCache 101 * Add a read-only cache path to search for images pre-cached by SDImageCache
@@ -103,7 +103,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -103,7 +103,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
103 * 103 *
104 * @param path The path to use for this read-only cache path 104 * @param path The path to use for this read-only cache path
105 */ 105 */
106 -- (void)addReadOnlyCachePath:(NSString *)path; 106 +- (void)addReadOnlyCachePath:(nonnull NSString *)path;
107 107
108 /** 108 /**
109 * Store an image into memory and disk cache at the given key. 109 * Store an image into memory and disk cache at the given key.
@@ -111,7 +111,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -111,7 +111,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
111 * @param image The image to store 111 * @param image The image to store
112 * @param key The unique image cache key, usually it's image absolute URL 112 * @param key The unique image cache key, usually it's image absolute URL
113 */ 113 */
114 -- (void)storeImage:(UIImage *)image forKey:(NSString *)key; 114 +- (void)storeImage:(nullable UIImage *)image forKey:(nullable NSString *)key;
115 115
116 /** 116 /**
117 * Store an image into memory and optionally disk cache at the given key. 117 * Store an image into memory and optionally disk cache at the given key.
@@ -120,7 +120,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -120,7 +120,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
120 * @param key The unique image cache key, usually it's image absolute URL 120 * @param key The unique image cache key, usually it's image absolute URL
121 * @param toDisk Store the image to disk cache if YES 121 * @param toDisk Store the image to disk cache if YES
122 */ 122 */
123 -- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk; 123 +- (void)storeImage:(nullable UIImage *)image forKey:(nullable NSString *)key toDisk:(BOOL)toDisk;
124 124
125 /** 125 /**
126 * Store an image into memory and optionally disk cache at the given key. 126 * Store an image into memory and optionally disk cache at the given key.
@@ -133,7 +133,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -133,7 +133,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
133 * @param key The unique image cache key, usually it's image absolute URL 133 * @param key The unique image cache key, usually it's image absolute URL
134 * @param toDisk Store the image to disk cache if YES 134 * @param toDisk Store the image to disk cache if YES
135 */ 135 */
136 -- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk; 136 +- (void)storeImage:(nullable UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(nullable NSData *)imageData forKey:(nullable NSString *)key toDisk:(BOOL)toDisk;
137 137
138 /** 138 /**
139 * Store image NSData into disk cache at the given key. 139 * Store image NSData into disk cache at the given key.
@@ -141,35 +141,35 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -141,35 +141,35 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
141 * @param imageData The image data to store 141 * @param imageData The image data to store
142 * @param key The unique image cache key, usually it's image absolute URL 142 * @param key The unique image cache key, usually it's image absolute URL
143 */ 143 */
144 -- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key; 144 +- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key;
145 145
146 /** 146 /**
147 * Query the disk cache asynchronously. 147 * Query the disk cache asynchronously.
148 * 148 *
149 * @param key The unique key used to store the wanted image 149 * @param key The unique key used to store the wanted image
150 */ 150 */
151 -- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDCacheQueryCompletedBlock)doneBlock; 151 +- (nullable NSOperation *)queryDiskCacheForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock;
152 152
153 /** 153 /**
154 * Query the memory cache synchronously. 154 * Query the memory cache synchronously.
155 * 155 *
156 * @param key The unique key used to store the wanted image 156 * @param key The unique key used to store the wanted image
157 */ 157 */
158 -- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key; 158 +- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key;
159 159
160 /** 160 /**
161 * Query the disk cache synchronously after checking the memory cache. 161 * Query the disk cache synchronously after checking the memory cache.
162 * 162 *
163 * @param key The unique key used to store the wanted image 163 * @param key The unique key used to store the wanted image
164 */ 164 */
165 -- (UIImage *)imageFromDiskCacheForKey:(NSString *)key; 165 +- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key;
166 166
167 /** 167 /**
168 * Remove the image from memory and disk cache asynchronously 168 * Remove the image from memory and disk cache asynchronously
169 * 169 *
170 * @param key The unique image cache key 170 * @param key The unique image cache key
171 */ 171 */
172 -- (void)removeImageForKey:(NSString *)key; 172 +- (void)removeImageForKey:(nullable NSString *)key;
173 173
174 174
175 /** 175 /**
@@ -178,7 +178,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -178,7 +178,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
178 * @param key The unique image cache key 178 * @param key The unique image cache key
179 * @param completion An block that should be executed after the image has been removed (optional) 179 * @param completion An block that should be executed after the image has been removed (optional)
180 */ 180 */
181 -- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion; 181 +- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion;
182 182
183 /** 183 /**
184 * Remove the image from memory and optionally disk cache asynchronously 184 * Remove the image from memory and optionally disk cache asynchronously
@@ -186,7 +186,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -186,7 +186,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
186 * @param key The unique image cache key 186 * @param key The unique image cache key
187 * @param fromDisk Also remove cache entry from disk if YES 187 * @param fromDisk Also remove cache entry from disk if YES
188 */ 188 */
189 -- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk; 189 +- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk;
190 190
191 /** 191 /**
192 * Remove the image from memory and optionally disk cache asynchronously 192 * Remove the image from memory and optionally disk cache asynchronously
@@ -195,7 +195,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -195,7 +195,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
195 * @param fromDisk Also remove cache entry from disk if YES 195 * @param fromDisk Also remove cache entry from disk if YES
196 * @param completion An block that should be executed after the image has been removed (optional) 196 * @param completion An block that should be executed after the image has been removed (optional)
197 */ 197 */
198 -- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion; 198 +- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion;
199 199
200 /** 200 /**
201 * Clear all memory cached images 201 * Clear all memory cached images
@@ -206,7 +206,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -206,7 +206,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
206 * Clear all disk cached images. Non-blocking method - returns immediately. 206 * Clear all disk cached images. Non-blocking method - returns immediately.
207 * @param completion An block that should be executed after cache expiration completes (optional) 207 * @param completion An block that should be executed after cache expiration completes (optional)
208 */ 208 */
209 -- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion; 209 +- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion;
210 210
211 /** 211 /**
212 * Clear all disk cached images 212 * Clear all disk cached images
@@ -218,7 +218,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -218,7 +218,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
218 * Remove all expired cached image from disk. Non-blocking method - returns immediately. 218 * Remove all expired cached image from disk. Non-blocking method - returns immediately.
219 * @param completionBlock An block that should be executed after cache expiration completes (optional) 219 * @param completionBlock An block that should be executed after cache expiration completes (optional)
220 */ 220 */
221 -- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock; 221 +- (void)cleanDiskWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock;
222 222
223 /** 223 /**
224 * Remove all expired cached image from disk 224 * Remove all expired cached image from disk
@@ -239,7 +239,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -239,7 +239,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
239 /** 239 /**
240 * Asynchronously calculate the disk cache's size. 240 * Asynchronously calculate the disk cache's size.
241 */ 241 */
242 -- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock; 242 +- (void)calculateSizeWithCompletionBlock:(nullable SDWebImageCalculateSizeBlock)completionBlock;
243 243
244 /** 244 /**
245 * Async check if image exists in disk cache already (does not load the image) 245 * Async check if image exists in disk cache already (does not load the image)
@@ -248,7 +248,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -248,7 +248,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
248 * @param completionBlock the block to be executed when the check is done. 248 * @param completionBlock the block to be executed when the check is done.
249 * @note the completion block will be always executed on the main queue 249 * @note the completion block will be always executed on the main queue
250 */ 250 */
251 -- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock; 251 +- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock;
252 252
253 /** 253 /**
254 * Check if image exists in disk cache already (does not load the image) 254 * Check if image exists in disk cache already (does not load the image)
@@ -257,7 +257,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -257,7 +257,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
257 * 257 *
258 * @return YES if an image exists for the given key 258 * @return YES if an image exists for the given key
259 */ 259 */
260 -- (BOOL)diskImageExistsWithKey:(NSString *)key; 260 +- (BOOL)diskImageExistsWithKey:(nullable NSString *)key;
261 261
262 /** 262 /**
263 * Get the cache path for a certain key (needs the cache path root folder) 263 * Get the cache path for a certain key (needs the cache path root folder)
@@ -267,7 +267,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -267,7 +267,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
267 * 267 *
268 * @return the cache path 268 * @return the cache path
269 */ 269 */
270 -- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path; 270 +- (nullable NSString *)cachePathForKey:(nullable NSString *)key inPath:(nonnull NSString *)path;
271 271
272 /** 272 /**
273 * Get the default cache path for a certain key 273 * Get the default cache path for a certain key
@@ -276,6 +276,6 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot @@ -276,6 +276,6 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
276 * 276 *
277 * @return the default cache path 277 * @return the default cache path
278 */ 278 */
279 -- (NSString *)defaultCachePathForKey:(NSString *)key; 279 +- (nullable NSString *)defaultCachePathForKey:(nullable NSString *)key;
280 280
281 @end 281 @end
@@ -18,8 +18,7 @@ @@ -18,8 +18,7 @@
18 18
19 @implementation AutoPurgeCache 19 @implementation AutoPurgeCache
20 20
21 -- (id)init  
22 -{ 21 +- (nonnull instancetype)init {
23 self = [super init]; 22 self = [super init];
24 if (self) { 23 if (self) {
25 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 24 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
@@ -27,8 +26,7 @@ @@ -27,8 +26,7 @@
27 return self; 26 return self;
28 } 27 }
29 28
30 -- (void)dealloc  
31 -{ 29 +- (void)dealloc {
32 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 30 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
33 31
34 } 32 }
@@ -59,10 +57,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -59,10 +57,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
59 57
60 @interface SDImageCache () 58 @interface SDImageCache ()
61 59
62 -@property (strong, nonatomic) NSCache *memCache;  
63 -@property (strong, nonatomic) NSString *diskCachePath;  
64 -@property (strong, nonatomic) NSMutableArray *customPaths;  
65 -@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t ioQueue; 60 +@property (strong, nonatomic, nonnull) NSCache *memCache;
  61 +@property (strong, nonatomic, nonnull) NSString *diskCachePath;
  62 +@property (strong, nonatomic, nullable) NSMutableArray<NSString *> *customPaths;
  63 +@property (SDDispatchQueueSetterSementics, nonatomic, nullable) dispatch_queue_t ioQueue;
66 64
67 @end 65 @end
68 66
@@ -71,7 +69,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -71,7 +69,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
71 NSFileManager *_fileManager; 69 NSFileManager *_fileManager;
72 } 70 }
73 71
74 -+ (SDImageCache *)sharedImageCache { 72 ++ (nonnull SDImageCache *)sharedImageCache {
75 static dispatch_once_t once; 73 static dispatch_once_t once;
76 static id instance; 74 static id instance;
77 dispatch_once(&once, ^{ 75 dispatch_once(&once, ^{
@@ -84,12 +82,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -84,12 +82,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
84 return [self initWithNamespace:@"default"]; 82 return [self initWithNamespace:@"default"];
85 } 83 }
86 84
87 -- (instancetype)initWithNamespace:(NSString *)ns { 85 +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns {
88 NSString *path = [self makeDiskCachePath:ns]; 86 NSString *path = [self makeDiskCachePath:ns];
89 return [self initWithNamespace:ns diskCacheDirectory:path]; 87 return [self initWithNamespace:ns diskCacheDirectory:path];
90 } 88 }
91 89
92 -- (instancetype)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory { 90 +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns
  91 + diskCacheDirectory:(nonnull NSString *)directory {
93 if ((self = [super init])) { 92 if ((self = [super init])) {
94 NSString *fullNamespace = [@"com.hackemist.SDWebImageCache." stringByAppendingString:ns]; 93 NSString *fullNamespace = [@"com.hackemist.SDWebImageCache." stringByAppendingString:ns];
95 94
@@ -154,7 +153,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -154,7 +153,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
154 SDDispatchQueueRelease(_ioQueue); 153 SDDispatchQueueRelease(_ioQueue);
155 } 154 }
156 155
157 -- (void)addReadOnlyCachePath:(NSString *)path { 156 +- (void)addReadOnlyCachePath:(nonnull NSString *)path {
158 if (!self.customPaths) { 157 if (!self.customPaths) {
159 self.customPaths = [NSMutableArray new]; 158 self.customPaths = [NSMutableArray new];
160 } 159 }
@@ -164,18 +163,18 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -164,18 +163,18 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
164 } 163 }
165 } 164 }
166 165
167 -- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path { 166 +- (nullable NSString *)cachePathForKey:(nullable NSString *)key inPath:(nonnull NSString *)path {
168 NSString *filename = [self cachedFileNameForKey:key]; 167 NSString *filename = [self cachedFileNameForKey:key];
169 return [path stringByAppendingPathComponent:filename]; 168 return [path stringByAppendingPathComponent:filename];
170 } 169 }
171 170
172 -- (NSString *)defaultCachePathForKey:(NSString *)key { 171 +- (nullable NSString *)defaultCachePathForKey:(nullable NSString *)key {
173 return [self cachePathForKey:key inPath:self.diskCachePath]; 172 return [self cachePathForKey:key inPath:self.diskCachePath];
174 } 173 }
175 174
176 #pragma mark SDImageCache (private) 175 #pragma mark SDImageCache (private)
177 176
178 -- (NSString *)cachedFileNameForKey:(NSString *)key { 177 +- (nullable NSString *)cachedFileNameForKey:(nullable NSString *)key {
179 const char *str = key.UTF8String; 178 const char *str = key.UTF8String;
180 if (str == NULL) { 179 if (str == NULL) {
181 str = ""; 180 str = "";
@@ -192,12 +191,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -192,12 +191,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
192 #pragma mark ImageCache 191 #pragma mark ImageCache
193 192
194 // Init the disk cache 193 // Init the disk cache
195 --(NSString *)makeDiskCachePath:(NSString*)fullNamespace{  
196 - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 194 +- (nullable NSString *)makeDiskCachePath:(nonnull NSString*)fullNamespace {
  195 + NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
197 return [paths[0] stringByAppendingPathComponent:fullNamespace]; 196 return [paths[0] stringByAppendingPathComponent:fullNamespace];
198 } 197 }
199 198
200 -- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk { 199 +- (void)storeImage:(nullable UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(nullable NSData *)imageData forKey:(nullable NSString *)key toDisk:(BOOL)toDisk {
201 if (!image || !key) { 200 if (!image || !key) {
202 return; 201 return;
203 } 202 }
@@ -247,15 +246,15 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -247,15 +246,15 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
247 } 246 }
248 } 247 }
249 248
250 -- (void)storeImage:(UIImage *)image forKey:(NSString *)key { 249 +- (void)storeImage:(nullable UIImage *)image forKey:(nullable NSString *)key {
251 [self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:YES]; 250 [self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:YES];
252 } 251 }
253 252
254 -- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk { 253 +- (void)storeImage:(nullable UIImage *)image forKey:(nullable NSString *)key toDisk:(BOOL)toDisk {
255 [self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:toDisk]; 254 [self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:toDisk];
256 } 255 }
257 256
258 -- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key { 257 +- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key {
259 258
260 if (!imageData) { 259 if (!imageData) {
261 return; 260 return;
@@ -278,7 +277,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -278,7 +277,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
278 } 277 }
279 } 278 }
280 279
281 -- (BOOL)diskImageExistsWithKey:(NSString *)key { 280 +- (BOOL)diskImageExistsWithKey:(nullable NSString *)key {
282 BOOL exists = NO; 281 BOOL exists = NO;
283 282
284 // this is an exception to access the filemanager on another queue than ioQueue, but we are using the shared instance 283 // this is an exception to access the filemanager on another queue than ioQueue, but we are using the shared instance
@@ -294,7 +293,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -294,7 +293,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
294 return exists; 293 return exists;
295 } 294 }
296 295
297 -- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock { 296 +- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock {
298 dispatch_async(_ioQueue, ^{ 297 dispatch_async(_ioQueue, ^{
299 BOOL exists = [_fileManager fileExistsAtPath:[self defaultCachePathForKey:key]]; 298 BOOL exists = [_fileManager fileExistsAtPath:[self defaultCachePathForKey:key]];
300 299
@@ -312,11 +311,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -312,11 +311,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
312 }); 311 });
313 } 312 }
314 313
315 -- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key { 314 +- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key {
316 return [self.memCache objectForKey:key]; 315 return [self.memCache objectForKey:key];
317 } 316 }
318 317
319 -- (UIImage *)imageFromDiskCacheForKey:(NSString *)key { 318 +- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key {
320 319
321 // First check the in-memory cache... 320 // First check the in-memory cache...
322 UIImage *image = [self imageFromMemoryCacheForKey:key]; 321 UIImage *image = [self imageFromMemoryCacheForKey:key];
@@ -334,7 +333,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -334,7 +333,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
334 return diskImage; 333 return diskImage;
335 } 334 }
336 335
337 -- (NSData *)diskImageDataBySearchingAllPathsForKey:(NSString *)key { 336 +- (nullable NSData *)diskImageDataBySearchingAllPathsForKey:(nullable NSString *)key {
338 NSString *defaultPath = [self defaultCachePathForKey:key]; 337 NSString *defaultPath = [self defaultCachePathForKey:key];
339 NSData *data = [NSData dataWithContentsOfFile:defaultPath]; 338 NSData *data = [NSData dataWithContentsOfFile:defaultPath];
340 if (data) { 339 if (data) {
@@ -348,7 +347,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -348,7 +347,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
348 return data; 347 return data;
349 } 348 }
350 349
351 - NSArray *customPaths = [self.customPaths copy]; 350 + NSArray<NSString *> *customPaths = [self.customPaths copy];
352 for (NSString *path in customPaths) { 351 for (NSString *path in customPaths) {
353 NSString *filePath = [self cachePathForKey:key inPath:path]; 352 NSString *filePath = [self cachePathForKey:key inPath:path];
354 NSData *imageData = [NSData dataWithContentsOfFile:filePath]; 353 NSData *imageData = [NSData dataWithContentsOfFile:filePath];
@@ -367,7 +366,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -367,7 +366,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
367 return nil; 366 return nil;
368 } 367 }
369 368
370 -- (UIImage *)diskImageForKey:(NSString *)key { 369 +- (nullable UIImage *)diskImageForKey:(nullable NSString *)key {
371 NSData *data = [self diskImageDataBySearchingAllPathsForKey:key]; 370 NSData *data = [self diskImageDataBySearchingAllPathsForKey:key];
372 if (data) { 371 if (data) {
373 UIImage *image = [UIImage sd_imageWithData:data]; 372 UIImage *image = [UIImage sd_imageWithData:data];
@@ -382,11 +381,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -382,11 +381,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
382 } 381 }
383 } 382 }
384 383
385 -- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image { 384 +- (nullable UIImage *)scaledImageForKey:(nullable NSString *)key image:(nullable UIImage *)image {
386 return SDScaledImageForKey(key, image); 385 return SDScaledImageForKey(key, image);
387 } 386 }
388 387
389 -- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDCacheQueryCompletedBlock)doneBlock { 388 +- (nullable NSOperation *)queryDiskCacheForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock {
390 if (!doneBlock) { 389 if (!doneBlock) {
391 return nil; 390 return nil;
392 } 391 }
@@ -430,19 +429,19 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -430,19 +429,19 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
430 return operation; 429 return operation;
431 } 430 }
432 431
433 -- (void)removeImageForKey:(NSString *)key { 432 +- (void)removeImageForKey:(nullable NSString *)key {
434 [self removeImageForKey:key withCompletion:nil]; 433 [self removeImageForKey:key withCompletion:nil];
435 } 434 }
436 435
437 -- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion { 436 +- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion {
438 [self removeImageForKey:key fromDisk:YES withCompletion:completion]; 437 [self removeImageForKey:key fromDisk:YES withCompletion:completion];
439 } 438 }
440 439
441 -- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk { 440 +- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk {
442 [self removeImageForKey:key fromDisk:fromDisk withCompletion:nil]; 441 [self removeImageForKey:key fromDisk:fromDisk withCompletion:nil];
443 } 442 }
444 443
445 -- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion { 444 +- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion {
446 445
447 if (key == nil) { 446 if (key == nil) {
448 return; 447 return;
@@ -492,8 +491,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -492,8 +491,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
492 [self clearDiskOnCompletion:nil]; 491 [self clearDiskOnCompletion:nil];
493 } 492 }
494 493
495 -- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion  
496 -{ 494 +- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion {
497 dispatch_async(self.ioQueue, ^{ 495 dispatch_async(self.ioQueue, ^{
498 [_fileManager removeItemAtPath:self.diskCachePath error:nil]; 496 [_fileManager removeItemAtPath:self.diskCachePath error:nil];
499 [_fileManager createDirectoryAtPath:self.diskCachePath 497 [_fileManager createDirectoryAtPath:self.diskCachePath
@@ -513,10 +511,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -513,10 +511,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
513 [self cleanDiskWithCompletionBlock:nil]; 511 [self cleanDiskWithCompletionBlock:nil];
514 } 512 }
515 513
516 -- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock { 514 +- (void)cleanDiskWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock {
517 dispatch_async(self.ioQueue, ^{ 515 dispatch_async(self.ioQueue, ^{
518 NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; 516 NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
519 - NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]; 517 + NSArray<NSString *> *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];
520 518
521 // This enumerator prefetches useful properties for our cache files. 519 // This enumerator prefetches useful properties for our cache files.
522 NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL 520 NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
@@ -525,16 +523,16 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -525,16 +523,16 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
525 errorHandler:NULL]; 523 errorHandler:NULL];
526 524
527 NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge]; 525 NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge];
528 - NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary]; 526 + NSMutableDictionary<NSURL *, NSDictionary<NSString *, id> *> *cacheFiles = [NSMutableDictionary dictionary];
529 NSUInteger currentCacheSize = 0; 527 NSUInteger currentCacheSize = 0;
530 528
531 // Enumerate all of the files in the cache directory. This loop has two purposes: 529 // Enumerate all of the files in the cache directory. This loop has two purposes:
532 // 530 //
533 // 1. Removing files that are older than the expiration date. 531 // 1. Removing files that are older than the expiration date.
534 // 2. Storing file attributes for the size-based cleanup pass. 532 // 2. Storing file attributes for the size-based cleanup pass.
535 - NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init]; 533 + NSMutableArray<NSURL *> *urlsToDelete = [[NSMutableArray alloc] init];
536 for (NSURL *fileURL in fileEnumerator) { 534 for (NSURL *fileURL in fileEnumerator) {
537 - NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL]; 535 + NSDictionary<NSString *, id> *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];
538 536
539 // Skip directories. 537 // Skip directories.
540 if ([resourceValues[NSURLIsDirectoryKey] boolValue]) { 538 if ([resourceValues[NSURLIsDirectoryKey] boolValue]) {
@@ -565,15 +563,15 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -565,15 +563,15 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
565 const NSUInteger desiredCacheSize = self.maxCacheSize / 2; 563 const NSUInteger desiredCacheSize = self.maxCacheSize / 2;
566 564
567 // Sort the remaining cache files by their last modification time (oldest first). 565 // Sort the remaining cache files by their last modification time (oldest first).
568 - NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent  
569 - usingComparator:^NSComparisonResult(id obj1, id obj2) {  
570 - return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]];  
571 - }]; 566 + NSArray<NSURL *> *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent
  567 + usingComparator:^NSComparisonResult(id obj1, id obj2) {
  568 + return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]];
  569 + }];
572 570
573 // Delete files until we fall below our desired cache size. 571 // Delete files until we fall below our desired cache size.
574 for (NSURL *fileURL in sortedFiles) { 572 for (NSURL *fileURL in sortedFiles) {
575 if ([_fileManager removeItemAtURL:fileURL error:nil]) { 573 if ([_fileManager removeItemAtURL:fileURL error:nil]) {
576 - NSDictionary *resourceValues = cacheFiles[fileURL]; 574 + NSDictionary<NSString *, id> *resourceValues = cacheFiles[fileURL];
577 NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; 575 NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
578 currentCacheSize -= totalAllocatedSize.unsignedIntegerValue; 576 currentCacheSize -= totalAllocatedSize.unsignedIntegerValue;
579 577
@@ -617,7 +615,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -617,7 +615,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
617 NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath]; 615 NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
618 for (NSString *fileName in fileEnumerator) { 616 for (NSString *fileName in fileEnumerator) {
619 NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName]; 617 NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
620 - NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; 618 + NSDictionary<NSString *, id> *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
621 size += [attrs fileSize]; 619 size += [attrs fileSize];
622 } 620 }
623 }); 621 });
@@ -633,7 +631,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @@ -633,7 +631,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
633 return count; 631 return count;
634 } 632 }
635 633
636 -- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock { 634 +- (void)calculateSizeWithCompletionBlock:(nullable SDWebImageCalculateSizeBlock)completionBlock {
637 NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; 635 NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
638 636
639 dispatch_async(self.ioQueue, ^{ 637 dispatch_async(self.ioQueue, ^{
@@ -12,13 +12,13 @@ @@ -12,13 +12,13 @@
12 #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag 12 #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
13 #endif 13 #endif
14 14
15 -inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) { 15 +inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) {
16 if (!image) { 16 if (!image) {
17 return nil; 17 return nil;
18 } 18 }
19 19
20 if ((image.images).count > 0) { 20 if ((image.images).count > 0) {
21 - NSMutableArray *scaledImages = [NSMutableArray array]; 21 + NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];
22 22
23 for (UIImage *tempImage in image.images) { 23 for (UIImage *tempImage in image.images) {
24 [scaledImages addObject:SDScaledImageForKey(key, tempImage)]; 24 [scaledImages addObject:SDScaledImageForKey(key, tempImage)];
@@ -12,6 +12,6 @@ @@ -12,6 +12,6 @@
12 12
13 @interface UIImage (ForceDecode) 13 @interface UIImage (ForceDecode)
14 14
15 -+ (UIImage *)decodedImageWithImage:(UIImage *)image; 15 ++ (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image;
16 16
17 @end 17 @end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 11
12 @implementation UIImage (ForceDecode) 12 @implementation UIImage (ForceDecode)
13 13
14 -+ (UIImage *)decodedImageWithImage:(UIImage *)image { 14 ++ (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image {
15 // while downloading huge amount of images 15 // while downloading huge amount of images
16 // autorelease the bitmap context 16 // autorelease the bitmap context
17 // and all vars to help system to free memory 17 // and all vars to help system to free memory
@@ -63,22 +63,25 @@ typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) { @@ -63,22 +63,25 @@ typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
63 SDWebImageDownloaderLIFOExecutionOrder 63 SDWebImageDownloaderLIFOExecutionOrder
64 }; 64 };
65 65
66 -extern NSString *const SDWebImageDownloadStartNotification;  
67 -extern NSString *const SDWebImageDownloadStopNotification; 66 +extern NSString * _Nonnull const SDWebImageDownloadStartNotification;
  67 +extern NSString * _Nonnull const SDWebImageDownloadStopNotification;
68 68
69 typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize); 69 typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize);
70 70
71 -typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished); 71 +typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished);
72 72
73 -typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers); 73 +typedef NSDictionary<NSString *, NSString *> SDHTTPHeadersDictionary;
  74 +typedef NSMutableDictionary<NSString *, NSString *> SDHTTPHeadersMutableDictionary;
  75 +
  76 +typedef SDHTTPHeadersDictionary * _Nullable (^SDWebImageDownloaderHeadersFilterBlock)(NSURL * _Nullable url, SDHTTPHeadersDictionary * _Nullable headers);
74 77
75 /** 78 /**
76 * A token associated with each download. Can be used to cancel a download 79 * A token associated with each download. Can be used to cancel a download
77 */ 80 */
78 @interface SDWebImageDownloadToken : NSObject 81 @interface SDWebImageDownloadToken : NSObject
79 82
80 -@property (nonatomic, strong) NSURL *url;  
81 -@property (nonatomic, strong) id downloadOperationCancelToken; 83 +@property (nonatomic, strong, nullable) NSURL *url;
  84 +@property (nonatomic, strong, nullable) id downloadOperationCancelToken;
82 85
83 @end 86 @end
84 87
@@ -118,22 +121,22 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi @@ -118,22 +121,22 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
118 * 121 *
119 * @return global shared instance of downloader class 122 * @return global shared instance of downloader class
120 */ 123 */
121 -+ (SDWebImageDownloader *)sharedDownloader; 124 ++ (nonnull SDWebImageDownloader *)sharedDownloader;
122 125
123 /** 126 /**
124 * Set the default URL credential to be set for request operations. 127 * Set the default URL credential to be set for request operations.
125 */ 128 */
126 -@property (strong, nonatomic) NSURLCredential *urlCredential; 129 +@property (strong, nonatomic, nullable) NSURLCredential *urlCredential;
127 130
128 /** 131 /**
129 * Set username 132 * Set username
130 */ 133 */
131 -@property (strong, nonatomic) NSString *username; 134 +@property (strong, nonatomic, nullable) NSString *username;
132 135
133 /** 136 /**
134 * Set password 137 * Set password
135 */ 138 */
136 -@property (strong, nonatomic) NSString *password; 139 +@property (strong, nonatomic, nullable) NSString *password;
137 140
138 /** 141 /**
139 * Set filter to pick headers for downloading image HTTP request. 142 * Set filter to pick headers for downloading image HTTP request.
@@ -141,7 +144,7 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi @@ -141,7 +144,7 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
141 * This block will be invoked for each downloading image request, returned 144 * This block will be invoked for each downloading image request, returned
142 * NSDictionary will be used as headers in corresponding HTTP request. 145 * NSDictionary will be used as headers in corresponding HTTP request.
143 */ 146 */
144 -@property (nonatomic, copy) SDWebImageDownloaderHeadersFilterBlock headersFilter; 147 +@property (nonatomic, copy, nullable) SDWebImageDownloaderHeadersFilterBlock headersFilter;
145 148
146 /** 149 /**
147 * Set a value for a HTTP header to be appended to each download HTTP request. 150 * Set a value for a HTTP header to be appended to each download HTTP request.
@@ -149,14 +152,14 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi @@ -149,14 +152,14 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
149 * @param value The value for the header field. Use `nil` value to remove the header. 152 * @param value The value for the header field. Use `nil` value to remove the header.
150 * @param field The name of the header field to set. 153 * @param field The name of the header field to set.
151 */ 154 */
152 -- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field; 155 +- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field;
153 156
154 /** 157 /**
155 * Returns the value of the specified HTTP header field. 158 * Returns the value of the specified HTTP header field.
156 * 159 *
157 * @return The value associated with the header field field, or `nil` if there is no corresponding header field. 160 * @return The value associated with the header field field, or `nil` if there is no corresponding header field.
158 */ 161 */
159 -- (NSString *)valueForHTTPHeaderField:(NSString *)field; 162 +- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field;
160 163
161 /** 164 /**
162 * Sets a subclass of `SDWebImageDownloaderOperation` as the default 165 * Sets a subclass of `SDWebImageDownloaderOperation` as the default
@@ -166,7 +169,7 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi @@ -166,7 +169,7 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
166 * @param operationClass The subclass of `SDWebImageDownloaderOperation` to set 169 * @param operationClass The subclass of `SDWebImageDownloaderOperation` to set
167 * as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`. 170 * as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`.
168 */ 171 */
169 -- (void)setOperationClass:(Class)operationClass; 172 +- (void)setOperationClass:(nullable Class)operationClass;
170 173
171 /** 174 /**
172 * Creates a SDWebImageDownloader async downloader instance with a given URL 175 * Creates a SDWebImageDownloader async downloader instance with a given URL
@@ -189,17 +192,17 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi @@ -189,17 +192,17 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
189 * 192 *
190 * @return A token (SDWebImageDownloadToken) that can be passed to -cancel: to cancel this operation 193 * @return A token (SDWebImageDownloadToken) that can be passed to -cancel: to cancel this operation
191 */ 194 */
192 -- (SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url  
193 - options:(SDWebImageDownloaderOptions)options  
194 - progress:(SDWebImageDownloaderProgressBlock)progressBlock  
195 - completed:(SDWebImageDownloaderCompletedBlock)completedBlock; 195 +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
  196 + options:(SDWebImageDownloaderOptions)options
  197 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  198 + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;
196 199
197 /** 200 /**
198 * Cancels a download that was previously queued using -downloadImageWithURL:options:progress:completed: 201 * Cancels a download that was previously queued using -downloadImageWithURL:options:progress:completed:
199 * 202 *
200 * @param token The token received from -downloadImageWithURL:options:progress:completed: that should be canceled. 203 * @param token The token received from -downloadImageWithURL:options:progress:completed: that should be canceled.
201 */ 204 */
202 -- (void)cancel:(SDWebImageDownloadToken *)token; 205 +- (void)cancel:(nullable SDWebImageDownloadToken *)token;
203 206
204 /** 207 /**
205 * Sets the download queue suspension state 208 * Sets the download queue suspension state
@@ -16,13 +16,13 @@ @@ -16,13 +16,13 @@
16 16
17 @interface SDWebImageDownloader () <NSURLSessionTaskDelegate, NSURLSessionDataDelegate> 17 @interface SDWebImageDownloader () <NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
18 18
19 -@property (strong, nonatomic) NSOperationQueue *downloadQueue;  
20 -@property (weak, nonatomic) NSOperation *lastAddedOperation;  
21 -@property (assign, nonatomic) Class operationClass;  
22 -@property (strong, nonatomic) NSMutableDictionary *URLOperations;  
23 -@property (strong, nonatomic) NSMutableDictionary *HTTPHeaders; 19 +@property (strong, nonatomic, nonnull) NSOperationQueue *downloadQueue;
  20 +@property (weak, nonatomic, nullable) NSOperation *lastAddedOperation;
  21 +@property (assign, nonatomic, nullable) Class operationClass;
  22 +@property (strong, nonatomic, nonnull) NSMutableDictionary<NSURL *, SDWebImageDownloaderOperation *> *URLOperations;
  23 +@property (strong, nonatomic, nullable) SDHTTPHeadersMutableDictionary *HTTPHeaders;
24 // This queue is used to serialize the handling of the network responses of all the download operation in a single queue 24 // This queue is used to serialize the handling of the network responses of all the download operation in a single queue
25 -@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t barrierQueue; 25 +@property (SDDispatchQueueSetterSementics, nonatomic, nullable) dispatch_queue_t barrierQueue;
26 26
27 // The session in which data tasks will run 27 // The session in which data tasks will run
28 @property (strong, nonatomic) NSURLSession *session; 28 @property (strong, nonatomic) NSURLSession *session;
@@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
54 } 54 }
55 } 55 }
56 56
57 -+ (SDWebImageDownloader *)sharedDownloader { 57 ++ (nonnull SDWebImageDownloader *)sharedDownloader {
58 static dispatch_once_t once; 58 static dispatch_once_t once;
59 static id instance; 59 static id instance;
60 dispatch_once(&once, ^{ 60 dispatch_once(&once, ^{
@@ -63,7 +63,7 @@ @@ -63,7 +63,7 @@
63 return instance; 63 return instance;
64 } 64 }
65 65
66 -- (instancetype)init { 66 +- (nonnull instancetype)init {
67 if ((self = [super init])) { 67 if ((self = [super init])) {
68 _operationClass = [SDWebImageDownloaderOperation class]; 68 _operationClass = [SDWebImageDownloaderOperation class];
69 _shouldDecompressImages = YES; 69 _shouldDecompressImages = YES;
@@ -102,7 +102,7 @@ @@ -102,7 +102,7 @@
102 SDDispatchQueueRelease(_barrierQueue); 102 SDDispatchQueueRelease(_barrierQueue);
103 } 103 }
104 104
105 -- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { 105 +- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field {
106 if (value) { 106 if (value) {
107 self.HTTPHeaders[field] = value; 107 self.HTTPHeaders[field] = value;
108 } 108 }
@@ -111,7 +111,7 @@ @@ -111,7 +111,7 @@
111 } 111 }
112 } 112 }
113 113
114 -- (NSString *)valueForHTTPHeaderField:(NSString *)field { 114 +- (nullable NSString *)valueForHTTPHeaderField:(nullable NSString *)field {
115 return self.HTTPHeaders[field]; 115 return self.HTTPHeaders[field];
116 } 116 }
117 117
@@ -127,14 +127,14 @@ @@ -127,14 +127,14 @@
127 return _downloadQueue.maxConcurrentOperationCount; 127 return _downloadQueue.maxConcurrentOperationCount;
128 } 128 }
129 129
130 -- (void)setOperationClass:(Class)operationClass { 130 +- (void)setOperationClass:(nullable Class)operationClass {
131 _operationClass = operationClass ?: [SDWebImageDownloaderOperation class]; 131 _operationClass = operationClass ?: [SDWebImageDownloaderOperation class];
132 } 132 }
133 133
134 -- (SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url  
135 - options:(SDWebImageDownloaderOptions)options  
136 - progress:(SDWebImageDownloaderProgressBlock)progressBlock  
137 - completed:(SDWebImageDownloaderCompletedBlock)completedBlock { 134 +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
  135 + options:(SDWebImageDownloaderOptions)options
  136 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  137 + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock {
138 __weak SDWebImageDownloader *wself = self; 138 __weak SDWebImageDownloader *wself = self;
139 139
140 return [self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^SDWebImageDownloaderOperation *{ 140 return [self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^SDWebImageDownloaderOperation *{
@@ -180,7 +180,7 @@ @@ -180,7 +180,7 @@
180 }]; 180 }];
181 } 181 }
182 182
183 -- (void)cancel:(SDWebImageDownloadToken *)token { 183 +- (void)cancel:(nullable SDWebImageDownloadToken *)token {
184 dispatch_barrier_async(self.barrierQueue, ^{ 184 dispatch_barrier_async(self.barrierQueue, ^{
185 SDWebImageDownloaderOperation *operation = self.URLOperations[token.url]; 185 SDWebImageDownloaderOperation *operation = self.URLOperations[token.url];
186 BOOL canceled = [operation cancel:token.downloadOperationCancelToken]; 186 BOOL canceled = [operation cancel:token.downloadOperationCancelToken];
@@ -190,10 +190,10 @@ @@ -190,10 +190,10 @@
190 }); 190 });
191 } 191 }
192 192
193 -- (SDWebImageDownloadToken *)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock  
194 - completedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock  
195 - forURL:(NSURL *)url  
196 - createCallback:(SDWebImageDownloaderOperation *(^)())createCallback { 193 +- (nullable SDWebImageDownloadToken *)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock
  194 + completedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock
  195 + forURL:(nullable NSURL *)url
  196 + createCallback:(SDWebImageDownloaderOperation *(^)())createCallback {
197 // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data. 197 // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data.
198 if (url == nil) { 198 if (url == nil) {
199 if (completedBlock != nil) { 199 if (completedBlock != nil) {
@@ -10,22 +10,22 @@ @@ -10,22 +10,22 @@
10 #import "SDWebImageDownloader.h" 10 #import "SDWebImageDownloader.h"
11 #import "SDWebImageOperation.h" 11 #import "SDWebImageOperation.h"
12 12
13 -extern NSString *const SDWebImageDownloadStartNotification;  
14 -extern NSString *const SDWebImageDownloadReceiveResponseNotification;  
15 -extern NSString *const SDWebImageDownloadStopNotification;  
16 -extern NSString *const SDWebImageDownloadFinishNotification; 13 +extern NSString * _Nonnull const SDWebImageDownloadStartNotification;
  14 +extern NSString * _Nonnull const SDWebImageDownloadReceiveResponseNotification;
  15 +extern NSString * _Nonnull const SDWebImageDownloadStopNotification;
  16 +extern NSString * _Nonnull const SDWebImageDownloadFinishNotification;
17 17
18 @interface SDWebImageDownloaderOperation : NSOperation <SDWebImageOperation, NSURLSessionTaskDelegate, NSURLSessionDataDelegate> 18 @interface SDWebImageDownloaderOperation : NSOperation <SDWebImageOperation, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
19 19
20 /** 20 /**
21 * The request used by the operation's task. 21 * The request used by the operation's task.
22 */ 22 */
23 -@property (strong, nonatomic, readonly) NSURLRequest *request; 23 +@property (strong, nonatomic, readonly, nullable) NSURLRequest *request;
24 24
25 /** 25 /**
26 * The operation's task 26 * The operation's task
27 */ 27 */
28 -@property (strong, nonatomic, readonly) NSURLSessionTask *dataTask; 28 +@property (strong, nonatomic, readonly, nullable) NSURLSessionTask *dataTask;
29 29
30 30
31 @property (assign, nonatomic) BOOL shouldDecompressImages; 31 @property (assign, nonatomic) BOOL shouldDecompressImages;
@@ -41,7 +41,7 @@ extern NSString *const SDWebImageDownloadFinishNotification; @@ -41,7 +41,7 @@ extern NSString *const SDWebImageDownloadFinishNotification;
41 * 41 *
42 * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. 42 * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.
43 */ 43 */
44 -@property (nonatomic, strong) NSURLCredential *credential; 44 +@property (nonatomic, strong, nullable) NSURLCredential *credential;
45 45
46 /** 46 /**
47 * The SDWebImageDownloaderOptions for the receiver. 47 * The SDWebImageDownloaderOptions for the receiver.
@@ -56,7 +56,7 @@ extern NSString *const SDWebImageDownloadFinishNotification; @@ -56,7 +56,7 @@ extern NSString *const SDWebImageDownloadFinishNotification;
56 /** 56 /**
57 * The response returned by the operation's connection. 57 * The response returned by the operation's connection.
58 */ 58 */
59 -@property (strong, nonatomic) NSURLResponse *response; 59 +@property (strong, nonatomic, nullable) NSURLResponse *response;
60 60
61 /** 61 /**
62 * Initializes a `SDWebImageDownloaderOperation` object 62 * Initializes a `SDWebImageDownloaderOperation` object
@@ -69,9 +69,9 @@ extern NSString *const SDWebImageDownloadFinishNotification; @@ -69,9 +69,9 @@ extern NSString *const SDWebImageDownloadFinishNotification;
69 * 69 *
70 * @return the initialized instance 70 * @return the initialized instance
71 */ 71 */
72 -- (instancetype)initWithRequest:(NSURLRequest *)request  
73 - inSession:(NSURLSession *)session  
74 - options:(SDWebImageDownloaderOptions)options NS_DESIGNATED_INITIALIZER; 72 +- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request
  73 + inSession:(nullable NSURLSession *)session
  74 + options:(SDWebImageDownloaderOptions)options NS_DESIGNATED_INITIALIZER;
75 75
76 /** 76 /**
77 * Adds handlers for progress and completion. Returns a tokent that can be passed to -cancel: to cancel this set of 77 * Adds handlers for progress and completion. Returns a tokent that can be passed to -cancel: to cancel this set of
@@ -84,8 +84,8 @@ extern NSString *const SDWebImageDownloadFinishNotification; @@ -84,8 +84,8 @@ extern NSString *const SDWebImageDownloadFinishNotification;
84 * 84 *
85 * @return the token to use to cancel this set of handlers 85 * @return the token to use to cancel this set of handlers
86 */ 86 */
87 -- (id)addHandlersForProgress:(SDWebImageDownloaderProgressBlock)progressBlock  
88 - completed:(SDWebImageDownloaderCompletedBlock)completedBlock; 87 +- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  88 + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock;
89 89
90 /** 90 /**
91 * Cancels a set of callbacks. Once all callbacks are canceled, the operation is cancelled. 91 * Cancels a set of callbacks. Once all callbacks are canceled, the operation is cancelled.
@@ -94,6 +94,6 @@ extern NSString *const SDWebImageDownloadFinishNotification; @@ -94,6 +94,6 @@ extern NSString *const SDWebImageDownloadFinishNotification;
94 * 94 *
95 * @return YES if the operation was stopped because this was the last token to be canceled. NO otherwise. 95 * @return YES if the operation was stopped because this was the last token to be canceled. NO otherwise.
96 */ 96 */
97 -- (BOOL)cancel:(id)token; 97 +- (BOOL)cancel:(nullable id)token;
98 98
99 @end 99 @end
@@ -20,24 +20,26 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis @@ -20,24 +20,26 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
20 static NSString *const kProgressCallbackKey = @"progress"; 20 static NSString *const kProgressCallbackKey = @"progress";
21 static NSString *const kCompletedCallbackKey = @"completed"; 21 static NSString *const kCompletedCallbackKey = @"completed";
22 22
  23 +typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
  24 +
23 @interface SDWebImageDownloaderOperation () 25 @interface SDWebImageDownloaderOperation ()
24 26
25 -@property (strong, nonatomic) NSMutableArray *callbackBlocks; 27 +@property (strong, nonatomic, nonnull) NSMutableArray<SDCallbacksDictionary *> *callbackBlocks;
26 28
27 @property (assign, nonatomic, getter = isExecuting) BOOL executing; 29 @property (assign, nonatomic, getter = isExecuting) BOOL executing;
28 @property (assign, nonatomic, getter = isFinished) BOOL finished; 30 @property (assign, nonatomic, getter = isFinished) BOOL finished;
29 -@property (strong, nonatomic) NSMutableData *imageData; 31 +@property (strong, nonatomic, nullable) NSMutableData *imageData;
30 32
31 // This is weak because it is injected by whoever manages this session. If this gets nil-ed out, we won't be able to run 33 // This is weak because it is injected by whoever manages this session. If this gets nil-ed out, we won't be able to run
32 // the task associated with this operation 34 // the task associated with this operation
33 -@property (weak, nonatomic) NSURLSession *unownedSession; 35 +@property (weak, nonatomic, nullable) NSURLSession *unownedSession;
34 // This is set if we're using not using an injected NSURLSession. We're responsible of invalidating this one 36 // This is set if we're using not using an injected NSURLSession. We're responsible of invalidating this one
35 -@property (strong, nonatomic) NSURLSession *ownedSession; 37 +@property (strong, nonatomic, nullable) NSURLSession *ownedSession;
36 38
37 -@property (strong, nonatomic, readwrite) NSURLSessionTask *dataTask; 39 +@property (strong, nonatomic, readwrite, nullable) NSURLSessionTask *dataTask;
38 40
39 -@property (strong, atomic) NSThread *thread;  
40 -@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t barrierQueue; 41 +@property (strong, atomic, nullable) NSThread *thread;
  42 +@property (SDDispatchQueueSetterSementics, nonatomic, nullable) dispatch_queue_t barrierQueue;
41 43
42 #if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 44 #if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
43 @property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskId; 45 @property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskId;
@@ -54,13 +56,13 @@ static NSString *const kCompletedCallbackKey = @"completed"; @@ -54,13 +56,13 @@ static NSString *const kCompletedCallbackKey = @"completed";
54 @synthesize executing = _executing; 56 @synthesize executing = _executing;
55 @synthesize finished = _finished; 57 @synthesize finished = _finished;
56 58
57 -- (instancetype)init { 59 +- (nonnull instancetype)init {
58 return [self initWithRequest:nil inSession:nil options:0]; 60 return [self initWithRequest:nil inSession:nil options:0];
59 } 61 }
60 62
61 -- (instancetype)initWithRequest:(NSURLRequest *)request  
62 - inSession:(NSURLSession *)session  
63 - options:(SDWebImageDownloaderOptions)options { 63 +- (nonnull instancetype)initWithRequest:(nullable NSURLRequest *)request
  64 + inSession:(nullable NSURLSession *)session
  65 + options:(SDWebImageDownloaderOptions)options {
64 if ((self = [super init])) { 66 if ((self = [super init])) {
65 _request = request; 67 _request = request;
66 _shouldDecompressImages = YES; 68 _shouldDecompressImages = YES;
@@ -80,9 +82,9 @@ static NSString *const kCompletedCallbackKey = @"completed"; @@ -80,9 +82,9 @@ static NSString *const kCompletedCallbackKey = @"completed";
80 SDDispatchQueueRelease(_barrierQueue); 82 SDDispatchQueueRelease(_barrierQueue);
81 } 83 }
82 84
83 -- (id)addHandlersForProgress:(SDWebImageDownloaderProgressBlock)progressBlock  
84 - completed:(SDWebImageDownloaderCompletedBlock)completedBlock {  
85 - NSMutableDictionary *callbacks = [NSMutableDictionary new]; 85 +- (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  86 + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock {
  87 + SDCallbacksDictionary *callbacks = [NSMutableDictionary new];
86 if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy]; 88 if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy];
87 if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy]; 89 if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy];
88 dispatch_barrier_async(self.barrierQueue, ^{ 90 dispatch_barrier_async(self.barrierQueue, ^{
@@ -91,8 +93,8 @@ static NSString *const kCompletedCallbackKey = @"completed"; @@ -91,8 +93,8 @@ static NSString *const kCompletedCallbackKey = @"completed";
91 return callbacks; 93 return callbacks;
92 } 94 }
93 95
94 -- (NSArray *)callbacksForKey:(NSString *)key {  
95 - __block NSMutableArray *callbacks = nil; 96 +- (nullable NSArray<id> *)callbacksForKey:(NSString *)key {
  97 + __block NSMutableArray<id> *callbacks = nil;
96 dispatch_sync(self.barrierQueue, ^{ 98 dispatch_sync(self.barrierQueue, ^{
97 // We need to remove [NSNull null] because there might not always be a progress block for each callback 99 // We need to remove [NSNull null] because there might not always be a progress block for each callback
98 callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy]; 100 callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy];
@@ -101,7 +103,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; @@ -101,7 +103,7 @@ static NSString *const kCompletedCallbackKey = @"completed";
101 return callbacks; 103 return callbacks;
102 } 104 }
103 105
104 -- (BOOL)cancel:(id)token { 106 +- (BOOL)cancel:(nullable id)token {
105 __block BOOL shouldCancel = NO; 107 __block BOOL shouldCancel = NO;
106 dispatch_barrier_sync(self.barrierQueue, ^{ 108 dispatch_barrier_sync(self.barrierQueue, ^{
107 [self.callbackBlocks removeObjectIdenticalTo:token]; 109 [self.callbackBlocks removeObjectIdenticalTo:token];
@@ -410,7 +412,7 @@ didReceiveResponse:(NSURLResponse *)response @@ -410,7 +412,7 @@ didReceiveResponse:(NSURLResponse *)response
410 #pragma mark NSURLSessionTaskDelegate 412 #pragma mark NSURLSessionTaskDelegate
411 413
412 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { 414 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
413 - NSArray *completionBlocks = [[self callbacksForKey:kCompletedCallbackKey] copy]; 415 + NSArray<id> *completionBlocks = [[self callbacksForKey:kCompletedCallbackKey] copy];
414 @synchronized(self) { 416 @synchronized(self) {
415 self.thread = nil; 417 self.thread = nil;
416 self.dataTask = nil; 418 self.dataTask = nil;
@@ -521,7 +523,7 @@ didReceiveResponse:(NSURLResponse *)response @@ -521,7 +523,7 @@ didReceiveResponse:(NSURLResponse *)response
521 } 523 }
522 } 524 }
523 525
524 -- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image { 526 +- (nullable UIImage *)scaledImageForKey:(nullable NSString *)key image:(nullable UIImage *)image {
525 return SDScaledImageForKey(key, image); 527 return SDScaledImageForKey(key, image);
526 } 528 }
527 529
@@ -90,11 +90,11 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { @@ -90,11 +90,11 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
90 SDWebImageAvoidAutoSetImage = 1 << 11 90 SDWebImageAvoidAutoSetImage = 1 << 11
91 }; 91 };
92 92
93 -typedef void(^SDExternalCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL); 93 +typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
94 94
95 -typedef void(^SDInternalCompletionBlock)(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL); 95 +typedef void(^SDInternalCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL);
96 96
97 -typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); 97 +typedef NSString * _Nullable (^SDWebImageCacheKeyFilterBlock)(NSURL * _Nullable url);
98 98
99 99
100 @class SDWebImageManager; 100 @class SDWebImageManager;
@@ -111,7 +111,7 @@ typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); @@ -111,7 +111,7 @@ typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url);
111 * 111 *
112 * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied. 112 * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied.
113 */ 113 */
114 -- (BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL; 114 +- (BOOL)imageManager:(nonnull SDWebImageManager *)imageManager shouldDownloadImageForURL:(nullable NSURL *)imageURL;
115 115
116 /** 116 /**
117 * Allows to transform the image immediately after it has been downloaded and just before to cache it on disk and memory. 117 * Allows to transform the image immediately after it has been downloaded and just before to cache it on disk and memory.
@@ -123,7 +123,7 @@ typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); @@ -123,7 +123,7 @@ typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url);
123 * 123 *
124 * @return The transformed image object. 124 * @return The transformed image object.
125 */ 125 */
126 -- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL; 126 +- (nullable UIImage *)imageManager:(nonnull SDWebImageManager *)imageManager transformDownloadedImage:(nullable UIImage *)image withURL:(nullable NSURL *)imageURL;
127 127
128 @end 128 @end
129 129
@@ -151,10 +151,10 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -151,10 +151,10 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
151 */ 151 */
152 @interface SDWebImageManager : NSObject 152 @interface SDWebImageManager : NSObject
153 153
154 -@property (weak, nonatomic) id <SDWebImageManagerDelegate> delegate; 154 +@property (weak, nonatomic, nullable) id <SDWebImageManagerDelegate> delegate;
155 155
156 -@property (strong, nonatomic, readonly) SDImageCache *imageCache;  
157 -@property (strong, nonatomic, readonly) SDWebImageDownloader *imageDownloader; 156 +@property (strong, nonatomic, readonly, nullable) SDImageCache *imageCache;
  157 +@property (strong, nonatomic, readonly, nullable) SDWebImageDownloader *imageDownloader;
158 158
159 /** 159 /**
160 * The cache filter is a block used each time SDWebImageManager need to convert an URL into a cache key. This can 160 * The cache filter is a block used each time SDWebImageManager need to convert an URL into a cache key. This can
@@ -172,20 +172,20 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -172,20 +172,20 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
172 172
173 * @endcode 173 * @endcode
174 */ 174 */
175 -@property (nonatomic, copy) SDWebImageCacheKeyFilterBlock cacheKeyFilter; 175 +@property (nonatomic, copy, nullable) SDWebImageCacheKeyFilterBlock cacheKeyFilter;
176 176
177 /** 177 /**
178 * Returns global SDWebImageManager instance. 178 * Returns global SDWebImageManager instance.
179 * 179 *
180 * @return SDWebImageManager shared instance 180 * @return SDWebImageManager shared instance
181 */ 181 */
182 -+ (SDWebImageManager *)sharedManager; 182 ++ (nonnull SDWebImageManager *)sharedManager;
183 183
184 /** 184 /**
185 * Allows to specify instance of cache and image downloader used with image manager. 185 * Allows to specify instance of cache and image downloader used with image manager.
186 * @return new instance of `SDWebImageManager` with specified cache and downloader. 186 * @return new instance of `SDWebImageManager` with specified cache and downloader.
187 */ 187 */
188 -- (instancetype)initWithCache:(SDImageCache *)cache downloader:(SDWebImageDownloader *)downloader; 188 +- (nonnull instancetype)initWithCache:(nonnull SDImageCache *)cache downloader:(nonnull SDWebImageDownloader *)downloader;
189 189
190 /** 190 /**
191 * Downloads the image at the given URL if not present in cache or return the cached version otherwise. 191 * Downloads the image at the given URL if not present in cache or return the cached version otherwise.
@@ -211,10 +211,10 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -211,10 +211,10 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
211 * 211 *
212 * @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation 212 * @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation
213 */ 213 */
214 -- (id <SDWebImageOperation>)loadImageWithURL:(NSURL *)url  
215 - options:(SDWebImageOptions)options  
216 - progress:(SDWebImageDownloaderProgressBlock)progressBlock  
217 - completed:(SDInternalCompletionBlock)completedBlock; 214 +- (nullable id <SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url
  215 + options:(SDWebImageOptions)options
  216 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  217 + completed:(nullable SDInternalCompletionBlock)completedBlock;
218 218
219 /** 219 /**
220 * Saves image to cache for given URL 220 * Saves image to cache for given URL
@@ -224,7 +224,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -224,7 +224,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
224 * 224 *
225 */ 225 */
226 226
227 -- (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url; 227 +- (void)saveImageToCache:(nullable UIImage *)image forURL:(nullable NSURL *)url;
228 228
229 /** 229 /**
230 * Cancel all current operations 230 * Cancel all current operations
@@ -243,7 +243,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -243,7 +243,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
243 * 243 *
244 * @return if the image was already cached 244 * @return if the image was already cached
245 */ 245 */
246 -- (BOOL)cachedImageExistsForURL:(NSURL *)url; 246 +- (BOOL)cachedImageExistsForURL:(nullable NSURL *)url;
247 247
248 /** 248 /**
249 * Check if image has already been cached on disk only 249 * Check if image has already been cached on disk only
@@ -252,7 +252,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -252,7 +252,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
252 * 252 *
253 * @return if the image was already cached (disk only) 253 * @return if the image was already cached (disk only)
254 */ 254 */
255 -- (BOOL)diskImageExistsForURL:(NSURL *)url; 255 +- (BOOL)diskImageExistsForURL:(nullable NSURL *)url;
256 256
257 /** 257 /**
258 * Async check if image has already been cached 258 * Async check if image has already been cached
@@ -262,8 +262,8 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -262,8 +262,8 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
262 * 262 *
263 * @note the completion block is always executed on the main queue 263 * @note the completion block is always executed on the main queue
264 */ 264 */
265 -- (void)cachedImageExistsForURL:(NSURL *)url  
266 - completion:(SDWebImageCheckCacheCompletionBlock)completionBlock; 265 +- (void)cachedImageExistsForURL:(nullable NSURL *)url
  266 + completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock;
267 267
268 /** 268 /**
269 * Async check if image has already been cached on disk only 269 * Async check if image has already been cached on disk only
@@ -273,13 +273,13 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -273,13 +273,13 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
273 * 273 *
274 * @note the completion block is always executed on the main queue 274 * @note the completion block is always executed on the main queue
275 */ 275 */
276 -- (void)diskImageExistsForURL:(NSURL *)url  
277 - completion:(SDWebImageCheckCacheCompletionBlock)completionBlock; 276 +- (void)diskImageExistsForURL:(nullable NSURL *)url
  277 + completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock;
278 278
279 279
280 /** 280 /**
281 *Return the cache key for a given URL 281 *Return the cache key for a given URL
282 */ 282 */
283 -- (NSString *)cacheKeyForURL:(NSURL *)url; 283 +- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url;
284 284
285 @end 285 @end
@@ -12,23 +12,23 @@ @@ -12,23 +12,23 @@
12 @interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation> 12 @interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation>
13 13
14 @property (assign, nonatomic, getter = isCancelled) BOOL cancelled; 14 @property (assign, nonatomic, getter = isCancelled) BOOL cancelled;
15 -@property (copy, nonatomic) SDWebImageNoParamsBlock cancelBlock;  
16 -@property (strong, nonatomic) NSOperation *cacheOperation; 15 +@property (copy, nonatomic, nullable) SDWebImageNoParamsBlock cancelBlock;
  16 +@property (strong, nonatomic, nullable) NSOperation *cacheOperation;
17 17
18 @end 18 @end
19 19
20 @interface SDWebImageManager () 20 @interface SDWebImageManager ()
21 21
22 -@property (strong, nonatomic, readwrite) SDImageCache *imageCache;  
23 -@property (strong, nonatomic, readwrite) SDWebImageDownloader *imageDownloader;  
24 -@property (strong, nonatomic) NSMutableSet *failedURLs;  
25 -@property (strong, nonatomic) NSMutableArray *runningOperations; 22 +@property (strong, nonatomic, readwrite, nonnull) SDImageCache *imageCache;
  23 +@property (strong, nonatomic, readwrite, nonnull) SDWebImageDownloader *imageDownloader;
  24 +@property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs;
  25 +@property (strong, nonatomic, nonnull) NSMutableArray<SDWebImageCombinedOperation *> *runningOperations;
26 26
27 @end 27 @end
28 28
29 @implementation SDWebImageManager 29 @implementation SDWebImageManager
30 30
31 -+ (SDWebImageManager*)sharedManager { 31 ++ (nonnull SDWebImageManager*)sharedManager {
32 static dispatch_once_t once; 32 static dispatch_once_t once;
33 static id instance; 33 static id instance;
34 dispatch_once(&once, ^{ 34 dispatch_once(&once, ^{
@@ -37,13 +37,13 @@ @@ -37,13 +37,13 @@
37 return instance; 37 return instance;
38 } 38 }
39 39
40 -- (instancetype)init { 40 +- (nonnull instancetype)init {
41 SDImageCache *cache = [SDImageCache sharedImageCache]; 41 SDImageCache *cache = [SDImageCache sharedImageCache];
42 SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader]; 42 SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
43 return [self initWithCache:cache downloader:downloader]; 43 return [self initWithCache:cache downloader:downloader];
44 } 44 }
45 45
46 -- (instancetype)initWithCache:(SDImageCache *)cache downloader:(SDWebImageDownloader *)downloader { 46 +- (nonnull instancetype)initWithCache:(nonnull SDImageCache *)cache downloader:(nonnull SDWebImageDownloader *)downloader {
47 if ((self = [super init])) { 47 if ((self = [super init])) {
48 _imageCache = cache; 48 _imageCache = cache;
49 _imageDownloader = downloader; 49 _imageDownloader = downloader;
@@ -53,37 +53,31 @@ @@ -53,37 +53,31 @@
53 return self; 53 return self;
54 } 54 }
55 55
56 -- (NSString *)cacheKeyForURL:(NSURL *)url { 56 +- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url {
57 if (!url) { 57 if (!url) {
58 return @""; 58 return @"";
59 } 59 }
60 - 60 +
61 if (self.cacheKeyFilter) { 61 if (self.cacheKeyFilter) {
62 return self.cacheKeyFilter(url); 62 return self.cacheKeyFilter(url);
63 } else { 63 } else {
64 - if (NSClassFromString(@"NSURLComponents") && [NSURLComponents instancesRespondToSelector:@selector(string)]) {  
65 - NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];  
66 - urlComponents.query = nil; // Strip out query parameters.  
67 - return urlComponents.URL.absoluteString;  
68 - } else {  
69 - return url.absoluteString;  
70 - } 64 + return url.absoluteString;
71 } 65 }
72 } 66 }
73 67
74 -- (BOOL)cachedImageExistsForURL:(NSURL *)url { 68 +- (BOOL)cachedImageExistsForURL:(nullable NSURL *)url {
75 NSString *key = [self cacheKeyForURL:url]; 69 NSString *key = [self cacheKeyForURL:url];
76 if ([self.imageCache imageFromMemoryCacheForKey:key] != nil) return YES; 70 if ([self.imageCache imageFromMemoryCacheForKey:key] != nil) return YES;
77 return [self.imageCache diskImageExistsWithKey:key]; 71 return [self.imageCache diskImageExistsWithKey:key];
78 } 72 }
79 73
80 -- (BOOL)diskImageExistsForURL:(NSURL *)url { 74 +- (BOOL)diskImageExistsForURL:(nullable NSURL *)url {
81 NSString *key = [self cacheKeyForURL:url]; 75 NSString *key = [self cacheKeyForURL:url];
82 return [self.imageCache diskImageExistsWithKey:key]; 76 return [self.imageCache diskImageExistsWithKey:key];
83 } 77 }
84 78
85 -- (void)cachedImageExistsForURL:(NSURL *)url  
86 - completion:(SDWebImageCheckCacheCompletionBlock)completionBlock { 79 +- (void)cachedImageExistsForURL:(nullable NSURL *)url
  80 + completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock {
87 NSString *key = [self cacheKeyForURL:url]; 81 NSString *key = [self cacheKeyForURL:url];
88 82
89 BOOL isInMemoryCache = ([self.imageCache imageFromMemoryCacheForKey:key] != nil); 83 BOOL isInMemoryCache = ([self.imageCache imageFromMemoryCacheForKey:key] != nil);
@@ -106,8 +100,8 @@ @@ -106,8 +100,8 @@
106 }]; 100 }];
107 } 101 }
108 102
109 -- (void)diskImageExistsForURL:(NSURL *)url  
110 - completion:(SDWebImageCheckCacheCompletionBlock)completionBlock { 103 +- (void)diskImageExistsForURL:(nullable NSURL *)url
  104 + completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock {
111 NSString *key = [self cacheKeyForURL:url]; 105 NSString *key = [self cacheKeyForURL:url];
112 106
113 [self.imageCache diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) { 107 [self.imageCache diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) {
@@ -118,10 +112,10 @@ @@ -118,10 +112,10 @@
118 }]; 112 }];
119 } 113 }
120 114
121 -- (id <SDWebImageOperation>)loadImageWithURL:(NSURL *)url 115 +- (id <SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url
122 options:(SDWebImageOptions)options 116 options:(SDWebImageOptions)options
123 - progress:(SDWebImageDownloaderProgressBlock)progressBlock  
124 - completed:(SDInternalCompletionBlock)completedBlock { 117 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  118 + completed:(nullable SDInternalCompletionBlock)completedBlock {
125 // Invoking this method without a completedBlock is pointless 119 // Invoking this method without a completedBlock is pointless
126 NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead"); 120 NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead");
127 121
@@ -140,8 +134,10 @@ @@ -140,8 +134,10 @@
140 __weak SDWebImageCombinedOperation *weakOperation = operation; 134 __weak SDWebImageCombinedOperation *weakOperation = operation;
141 135
142 BOOL isFailedUrl = NO; 136 BOOL isFailedUrl = NO;
143 - @synchronized (self.failedURLs) {  
144 - isFailedUrl = [self.failedURLs containsObject:url]; 137 + if (url) {
  138 + @synchronized (self.failedURLs) {
  139 + isFailedUrl = [self.failedURLs containsObject:url];
  140 + }
145 } 141 }
146 142
147 if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) { 143 if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {
@@ -299,7 +295,7 @@ @@ -299,7 +295,7 @@
299 return operation; 295 return operation;
300 } 296 }
301 297
302 -- (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url { 298 +- (void)saveImageToCache:(nullable UIImage *)image forURL:(nullable NSURL *)url {
303 if (image && url) { 299 if (image && url) {
304 NSString *key = [self cacheKeyForURL:url]; 300 NSString *key = [self cacheKeyForURL:url];
305 [self.imageCache storeImage:image forKey:key toDisk:YES]; 301 [self.imageCache storeImage:image forKey:key toDisk:YES];
@@ -308,7 +304,7 @@ @@ -308,7 +304,7 @@
308 304
309 - (void)cancelAll { 305 - (void)cancelAll {
310 @synchronized (self.runningOperations) { 306 @synchronized (self.runningOperations) {
311 - NSArray *copiedOperations = [self.runningOperations copy]; 307 + NSArray<SDWebImageCombinedOperation *> *copiedOperations = [self.runningOperations copy];
312 [copiedOperations makeObjectsPerformSelector:@selector(cancel)]; 308 [copiedOperations makeObjectsPerformSelector:@selector(cancel)];
313 [self.runningOperations removeObjectsInArray:copiedOperations]; 309 [self.runningOperations removeObjectsInArray:copiedOperations];
314 } 310 }
@@ -327,7 +323,7 @@ @@ -327,7 +323,7 @@
327 323
328 @implementation SDWebImageCombinedOperation 324 @implementation SDWebImageCombinedOperation
329 325
330 -- (void)setCancelBlock:(SDWebImageNoParamsBlock)cancelBlock { 326 +- (void)setCancelBlock:(nullable SDWebImageNoParamsBlock)cancelBlock {
331 // check if the operation is already cancelled, then we just call the cancelBlock 327 // check if the operation is already cancelled, then we just call the cancelBlock
332 if (self.isCancelled) { 328 if (self.isCancelled) {
333 if (cancelBlock) { 329 if (cancelBlock) {
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 * @param finishedCount The total number of images that were prefetched (successful or not) 23 * @param finishedCount The total number of images that were prefetched (successful or not)
24 * @param totalCount The total number of images that were to be prefetched 24 * @param totalCount The total number of images that were to be prefetched
25 */ 25 */
26 -- (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount; 26 +- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(nullable NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount;
27 27
28 /** 28 /**
29 * Called when all images are prefetched. 29 * Called when all images are prefetched.
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 * @param totalCount The total number of images that were prefetched (whether successful or not) 31 * @param totalCount The total number of images that were prefetched (whether successful or not)
32 * @param skippedCount The total number of images that were skipped 32 * @param skippedCount The total number of images that were skipped
33 */ 33 */
34 -- (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount; 34 +- (void)imagePrefetcher:(nonnull SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount;
35 35
36 @end 36 @end
37 37
@@ -46,7 +46,7 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, @@ -46,7 +46,7 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls,
46 /** 46 /**
47 * The web image manager 47 * The web image manager
48 */ 48 */
49 -@property (strong, nonatomic, readonly) SDWebImageManager *manager; 49 +@property (strong, nonatomic, readonly, nonnull) SDWebImageManager *manager;
50 50
51 /** 51 /**
52 * Maximum number of URLs to prefetch at the same time. Defaults to 3. 52 * Maximum number of URLs to prefetch at the same time. Defaults to 3.
@@ -61,19 +61,19 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, @@ -61,19 +61,19 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls,
61 /** 61 /**
62 * Queue options for Prefetcher. Defaults to Main Queue. 62 * Queue options for Prefetcher. Defaults to Main Queue.
63 */ 63 */
64 -@property (nonatomic, assign) dispatch_queue_t prefetcherQueue; 64 +@property (nonatomic, assign, nonnull) dispatch_queue_t prefetcherQueue;
65 65
66 -@property (weak, nonatomic) id <SDWebImagePrefetcherDelegate> delegate; 66 +@property (weak, nonatomic, nullable) id <SDWebImagePrefetcherDelegate> delegate;
67 67
68 /** 68 /**
69 * Return the global image prefetcher instance. 69 * Return the global image prefetcher instance.
70 */ 70 */
71 -+ (SDWebImagePrefetcher *)sharedImagePrefetcher; 71 ++ (nonnull SDWebImagePrefetcher *)sharedImagePrefetcher;
72 72
73 /** 73 /**
74 * Allows you to instantiate a prefetcher with any arbitrary image manager. 74 * Allows you to instantiate a prefetcher with any arbitrary image manager.
75 */ 75 */
76 -- (instancetype)initWithImageManager:(SDWebImageManager *)manager NS_DESIGNATED_INITIALIZER; 76 +- (nonnull instancetype)initWithImageManager:(nonnull SDWebImageManager *)manager NS_DESIGNATED_INITIALIZER;
77 77
78 /** 78 /**
79 * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 79 * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
@@ -82,7 +82,7 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, @@ -82,7 +82,7 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls,
82 * 82 *
83 * @param urls list of URLs to prefetch 83 * @param urls list of URLs to prefetch
84 */ 84 */
85 -- (void)prefetchURLs:(NSArray *)urls; 85 +- (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls;
86 86
87 /** 87 /**
88 * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 88 * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
@@ -97,7 +97,9 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, @@ -97,7 +97,9 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls,
97 * first param is the number of completed (successful or not) requests, 97 * first param is the number of completed (successful or not) requests,
98 * second parameter is the number of skipped requests 98 * second parameter is the number of skipped requests
99 */ 99 */
100 -- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock; 100 +- (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls
  101 + progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock
  102 + completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock;
101 103
102 /** 104 /**
103 * Remove and cancel queued list 105 * Remove and cancel queued list
@@ -10,20 +10,20 @@ @@ -10,20 +10,20 @@
10 10
11 @interface SDWebImagePrefetcher () 11 @interface SDWebImagePrefetcher ()
12 12
13 -@property (strong, nonatomic) SDWebImageManager *manager;  
14 -@property (strong, nonatomic) NSArray *prefetchURLs; 13 +@property (strong, nonatomic, nonnull) SDWebImageManager *manager;
  14 +@property (strong, nonatomic, nullable) NSArray<NSURL *> *prefetchURLs;
15 @property (assign, nonatomic) NSUInteger requestedCount; 15 @property (assign, nonatomic) NSUInteger requestedCount;
16 @property (assign, nonatomic) NSUInteger skippedCount; 16 @property (assign, nonatomic) NSUInteger skippedCount;
17 @property (assign, nonatomic) NSUInteger finishedCount; 17 @property (assign, nonatomic) NSUInteger finishedCount;
18 @property (assign, nonatomic) NSTimeInterval startedTime; 18 @property (assign, nonatomic) NSTimeInterval startedTime;
19 -@property (copy, nonatomic) SDWebImagePrefetcherCompletionBlock completionBlock;  
20 -@property (copy, nonatomic) SDWebImagePrefetcherProgressBlock progressBlock; 19 +@property (copy, nonatomic, nullable) SDWebImagePrefetcherCompletionBlock completionBlock;
  20 +@property (copy, nonatomic, nullable) SDWebImagePrefetcherProgressBlock progressBlock;
21 21
22 @end 22 @end
23 23
24 @implementation SDWebImagePrefetcher 24 @implementation SDWebImagePrefetcher
25 25
26 -+ (SDWebImagePrefetcher *)sharedImagePrefetcher { 26 ++ (nonnull SDWebImagePrefetcher *)sharedImagePrefetcher {
27 static dispatch_once_t once; 27 static dispatch_once_t once;
28 static id instance; 28 static id instance;
29 dispatch_once(&once, ^{ 29 dispatch_once(&once, ^{
@@ -32,11 +32,11 @@ @@ -32,11 +32,11 @@
32 return instance; 32 return instance;
33 } 33 }
34 34
35 -- (instancetype)init { 35 +- (nonnull instancetype)init {
36 return [self initWithImageManager:[SDWebImageManager new]]; 36 return [self initWithImageManager:[SDWebImageManager new]];
37 } 37 }
38 38
39 -- (instancetype)initWithImageManager:(SDWebImageManager *)manager { 39 +- (nonnull instancetype)initWithImageManager:(SDWebImageManager *)manager {
40 if ((self = [super init])) { 40 if ((self = [super init])) {
41 _manager = manager; 41 _manager = manager;
42 _options = SDWebImageLowPriority; 42 _options = SDWebImageLowPriority;
@@ -105,11 +105,13 @@ @@ -105,11 +105,13 @@
105 } 105 }
106 } 106 }
107 107
108 -- (void)prefetchURLs:(NSArray *)urls { 108 +- (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls {
109 [self prefetchURLs:urls progress:nil completed:nil]; 109 [self prefetchURLs:urls progress:nil completed:nil];
110 } 110 }
111 111
112 -- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock { 112 +- (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls
  113 + progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock
  114 + completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock {
113 [self cancelPrefetching]; // Prevent duplicate prefetch request 115 [self cancelPrefetching]; // Prevent duplicate prefetch request
114 self.startedTime = CFAbsoluteTimeGetCurrent(); 116 self.startedTime = CFAbsoluteTimeGetCurrent();
115 self.prefetchURLs = urls; 117 self.prefetchURLs = urls;
@@ -17,14 +17,14 @@ @@ -17,14 +17,14 @@
17 /** 17 /**
18 * Get the current image URL. 18 * Get the current image URL.
19 */ 19 */
20 -- (NSURL *)sd_currentImageURL; 20 +- (nullable NSURL *)sd_currentImageURL;
21 21
22 /** 22 /**
23 * Get the image URL for a control state. 23 * Get the image URL for a control state.
24 * 24 *
25 * @param state Which state you want to know the URL for. The values are described in UIControlState. 25 * @param state Which state you want to know the URL for. The values are described in UIControlState.
26 */ 26 */
27 -- (NSURL *)sd_imageURLForState:(UIControlState)state; 27 +- (nullable NSURL *)sd_imageURLForState:(UIControlState)state;
28 28
29 /** 29 /**
30 * Set the imageView `image` with an `url`. 30 * Set the imageView `image` with an `url`.
@@ -34,7 +34,8 @@ @@ -34,7 +34,8 @@
34 * @param url The url for the image. 34 * @param url The url for the image.
35 * @param state The state that uses the specified title. The values are described in UIControlState. 35 * @param state The state that uses the specified title. The values are described in UIControlState.
36 */ 36 */
37 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state; 37 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  38 + forState:(UIControlState)state;
38 39
39 /** 40 /**
40 * Set the imageView `image` with an `url` and a placeholder. 41 * Set the imageView `image` with an `url` and a placeholder.
@@ -46,7 +47,9 @@ @@ -46,7 +47,9 @@
46 * @param placeholder The image to be set initially, until the image request finishes. 47 * @param placeholder The image to be set initially, until the image request finishes.
47 * @see sd_setImageWithURL:placeholderImage:options: 48 * @see sd_setImageWithURL:placeholderImage:options:
48 */ 49 */
49 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; 50 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  51 + forState:(UIControlState)state
  52 + placeholderImage:(nullable UIImage *)placeholder;
50 53
51 /** 54 /**
52 * Set the imageView `image` with an `url`, placeholder and custom options. 55 * Set the imageView `image` with an `url`, placeholder and custom options.
@@ -58,7 +61,10 @@ @@ -58,7 +61,10 @@
58 * @param placeholder The image to be set initially, until the image request finishes. 61 * @param placeholder The image to be set initially, until the image request finishes.
59 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 62 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
60 */ 63 */
61 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 64 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  65 + forState:(UIControlState)state
  66 + placeholderImage:(nullable UIImage *)placeholder
  67 + options:(SDWebImageOptions)options;
62 68
63 /** 69 /**
64 * Set the imageView `image` with an `url`. 70 * Set the imageView `image` with an `url`.
@@ -73,7 +79,9 @@ @@ -73,7 +79,9 @@
73 * indicating if the image was retrieved from the local cache or from the network. 79 * indicating if the image was retrieved from the local cache or from the network.
74 * The fourth parameter is the original image url. 80 * The fourth parameter is the original image url.
75 */ 81 */
76 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock; 82 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  83 + forState:(UIControlState)state
  84 + completed:(nullable SDExternalCompletionBlock)completedBlock;
77 85
78 /** 86 /**
79 * Set the imageView `image` with an `url`, placeholder. 87 * Set the imageView `image` with an `url`, placeholder.
@@ -89,7 +97,10 @@ @@ -89,7 +97,10 @@
89 * indicating if the image was retrieved from the local cache or from the network. 97 * indicating if the image was retrieved from the local cache or from the network.
90 * The fourth parameter is the original image url. 98 * The fourth parameter is the original image url.
91 */ 99 */
92 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; 100 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  101 + forState:(UIControlState)state
  102 + placeholderImage:(nullable UIImage *)placeholder
  103 + completed:(nullable SDExternalCompletionBlock)completedBlock;
93 104
94 /** 105 /**
95 * Set the imageView `image` with an `url`, placeholder and custom options. 106 * Set the imageView `image` with an `url`, placeholder and custom options.
@@ -106,7 +117,11 @@ @@ -106,7 +117,11 @@
106 * indicating if the image was retrieved from the local cache or from the network. 117 * indicating if the image was retrieved from the local cache or from the network.
107 * The fourth parameter is the original image url. 118 * The fourth parameter is the original image url.
108 */ 119 */
109 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; 120 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  121 + forState:(UIControlState)state
  122 + placeholderImage:(nullable UIImage *)placeholder
  123 + options:(SDWebImageOptions)options
  124 + completed:(nullable SDExternalCompletionBlock)completedBlock;
110 125
111 /** 126 /**
112 * Set the backgroundImageView `image` with an `url`. 127 * Set the backgroundImageView `image` with an `url`.
@@ -116,7 +131,8 @@ @@ -116,7 +131,8 @@
116 * @param url The url for the image. 131 * @param url The url for the image.
117 * @param state The state that uses the specified title. The values are described in UIControlState. 132 * @param state The state that uses the specified title. The values are described in UIControlState.
118 */ 133 */
119 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state; 134 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  135 + forState:(UIControlState)state;
120 136
121 /** 137 /**
122 * Set the backgroundImageView `image` with an `url` and a placeholder. 138 * Set the backgroundImageView `image` with an `url` and a placeholder.
@@ -128,7 +144,9 @@ @@ -128,7 +144,9 @@
128 * @param placeholder The image to be set initially, until the image request finishes. 144 * @param placeholder The image to be set initially, until the image request finishes.
129 * @see sd_setImageWithURL:placeholderImage:options: 145 * @see sd_setImageWithURL:placeholderImage:options:
130 */ 146 */
131 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; 147 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  148 + forState:(UIControlState)state
  149 + placeholderImage:(nullable UIImage *)placeholder;
132 150
133 /** 151 /**
134 * Set the backgroundImageView `image` with an `url`, placeholder and custom options. 152 * Set the backgroundImageView `image` with an `url`, placeholder and custom options.
@@ -140,7 +158,10 @@ @@ -140,7 +158,10 @@
140 * @param placeholder The image to be set initially, until the image request finishes. 158 * @param placeholder The image to be set initially, until the image request finishes.
141 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 159 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
142 */ 160 */
143 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 161 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  162 + forState:(UIControlState)state
  163 + placeholderImage:(nullable UIImage *)placeholder
  164 + options:(SDWebImageOptions)options;
144 165
145 /** 166 /**
146 * Set the backgroundImageView `image` with an `url`. 167 * Set the backgroundImageView `image` with an `url`.
@@ -155,7 +176,9 @@ @@ -155,7 +176,9 @@
155 * indicating if the image was retrieved from the local cache or from the network. 176 * indicating if the image was retrieved from the local cache or from the network.
156 * The fourth parameter is the original image url. 177 * The fourth parameter is the original image url.
157 */ 178 */
158 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock; 179 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  180 + forState:(UIControlState)state
  181 + completed:(nullable SDExternalCompletionBlock)completedBlock;
159 182
160 /** 183 /**
161 * Set the backgroundImageView `image` with an `url`, placeholder. 184 * Set the backgroundImageView `image` with an `url`, placeholder.
@@ -171,7 +194,10 @@ @@ -171,7 +194,10 @@
171 * indicating if the image was retrieved from the local cache or from the network. 194 * indicating if the image was retrieved from the local cache or from the network.
172 * The fourth parameter is the original image url. 195 * The fourth parameter is the original image url.
173 */ 196 */
174 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; 197 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  198 + forState:(UIControlState)state
  199 + placeholderImage:(nullable UIImage *)placeholder
  200 + completed:(nullable SDExternalCompletionBlock)completedBlock;
175 201
176 /** 202 /**
177 * Set the backgroundImageView `image` with an `url`, placeholder and custom options. 203 * Set the backgroundImageView `image` with an `url`, placeholder and custom options.
@@ -187,7 +213,11 @@ @@ -187,7 +213,11 @@
187 * indicating if the image was retrieved from the local cache or from the network. 213 * indicating if the image was retrieved from the local cache or from the network.
188 * The fourth parameter is the original image url. 214 * The fourth parameter is the original image url.
189 */ 215 */
190 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; 216 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  217 + forState:(UIControlState)state
  218 + placeholderImage:(nullable UIImage *)placeholder
  219 + options:(SDWebImageOptions)options
  220 + completed:(nullable SDExternalCompletionBlock)completedBlock;
191 221
192 /** 222 /**
193 * Cancel the current image download 223 * Cancel the current image download
@@ -12,9 +12,11 @@ @@ -12,9 +12,11 @@
12 12
13 static char imageURLStorageKey; 13 static char imageURLStorageKey;
14 14
  15 +typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary;
  16 +
15 @implementation UIButton (WebCache) 17 @implementation UIButton (WebCache)
16 18
17 -- (NSURL *)sd_currentImageURL { 19 +- (nullable NSURL *)sd_currentImageURL {
18 NSURL *url = self.imageURLStorage[@(self.state)]; 20 NSURL *url = self.imageURLStorage[@(self.state)];
19 21
20 if (!url) { 22 if (!url) {
@@ -24,32 +26,35 @@ static char imageURLStorageKey; @@ -24,32 +26,35 @@ static char imageURLStorageKey;
24 return url; 26 return url;
25 } 27 }
26 28
27 -- (NSURL *)sd_imageURLForState:(UIControlState)state { 29 +- (nullable NSURL *)sd_imageURLForState:(UIControlState)state {
28 return self.imageURLStorage[@(state)]; 30 return self.imageURLStorage[@(state)];
29 } 31 }
30 32
31 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state { 33 +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {
32 [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; 34 [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
33 } 35 }
34 36
35 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { 37 +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder {
36 [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; 38 [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
37 } 39 }
38 40
39 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 41 +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
40 [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; 42 [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
41 } 43 }
42 44
43 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock { 45 +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock {
44 [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; 46 [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
45 } 47 }
46 48
47 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { 49 +- (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
48 [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; 50 [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
49 } 51 }
50 52
51 -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock {  
52 - 53 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  54 + forState:(UIControlState)state
  55 + placeholderImage:(nullable UIImage *)placeholder
  56 + options:(SDWebImageOptions)options
  57 + completed:(nullable SDExternalCompletionBlock)completedBlock {
53 [self setImage:placeholder forState:state]; 58 [self setImage:placeholder forState:state];
54 [self sd_cancelImageLoadForState:state]; 59 [self sd_cancelImageLoadForState:state];
55 60
@@ -90,27 +95,31 @@ static char imageURLStorageKey; @@ -90,27 +95,31 @@ static char imageURLStorageKey;
90 [self sd_setImageLoadOperation:operation forState:state]; 95 [self sd_setImageLoadOperation:operation forState:state];
91 } 96 }
92 97
93 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state { 98 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {
94 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; 99 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
95 } 100 }
96 101
97 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { 102 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder {
98 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; 103 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
99 } 104 }
100 105
101 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 106 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
102 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; 107 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
103 } 108 }
104 109
105 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock { 110 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock {
106 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; 111 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
107 } 112 }
108 113
109 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { 114 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
110 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; 115 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
111 } 116 }
112 117
113 -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { 118 +- (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  119 + forState:(UIControlState)state
  120 + placeholderImage:(nullable UIImage *)placeholder
  121 + options:(SDWebImageOptions)options
  122 + completed:(nullable SDExternalCompletionBlock)completedBlock {
114 [self sd_cancelBackgroundImageLoadForState:state]; 123 [self sd_cancelBackgroundImageLoadForState:state];
115 124
116 [self setBackgroundImage:placeholder forState:state]; 125 [self setBackgroundImage:placeholder forState:state];
@@ -162,8 +171,8 @@ static char imageURLStorageKey; @@ -162,8 +171,8 @@ static char imageURLStorageKey;
162 [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; 171 [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
163 } 172 }
164 173
165 -- (NSMutableDictionary *)imageURLStorage {  
166 - NSMutableDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); 174 +- (SDStateImageURLDictionary *)imageURLStorage {
  175 + SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey);
167 if (!storage) 176 if (!storage)
168 { 177 {
169 storage = [NSMutableDictionary dictionary]; 178 storage = [NSMutableDictionary dictionary];
@@ -10,6 +10,6 @@ @@ -10,6 +10,6 @@
10 10
11 @interface UIImage (MultiFormat) 11 @interface UIImage (MultiFormat)
12 12
13 -+ (UIImage *)sd_imageWithData:(NSData *)data; 13 ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data;
14 14
15 @end 15 @end
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 17
18 @implementation UIImage (MultiFormat) 18 @implementation UIImage (MultiFormat)
19 19
20 -+ (UIImage *)sd_imageWithData:(NSData *)data { 20 ++ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data {
21 if (!data) { 21 if (!data) {
22 return nil; 22 return nil;
23 } 23 }
@@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
48 } 48 }
49 49
50 50
51 -+(UIImageOrientation)sd_imageOrientationFromImageData:(NSData *)imageData { 51 ++(UIImageOrientation)sd_imageOrientationFromImageData:(nonnull NSData *)imageData {
52 UIImageOrientation result = UIImageOrientationUp; 52 UIImageOrientation result = UIImageOrientationUp;
53 CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL); 53 CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
54 if (imageSource) { 54 if (imageSource) {
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 12
13 @interface UIImage (WebP) 13 @interface UIImage (WebP)
14 14
15 -+ (UIImage *)sd_imageWithWebPData:(NSData *)data; 15 ++ (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data;
16 16
17 @end 17 @end
18 18
@@ -16,14 +16,13 @@ @@ -16,14 +16,13 @@
16 #endif 16 #endif
17 17
18 // Callback for CGDataProviderRelease 18 // Callback for CGDataProviderRelease
19 -static void FreeImageData(void *info, const void *data, size_t size)  
20 -{ 19 +static void FreeImageData(void *info, const void *data, size_t size) {
21 free((void *)data); 20 free((void *)data);
22 } 21 }
23 22
24 @implementation UIImage (WebP) 23 @implementation UIImage (WebP)
25 24
26 -+ (UIImage *)sd_imageWithWebPData:(NSData *)data { 25 ++ (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data {
27 WebPDecoderConfig config; 26 WebPDecoderConfig config;
28 if (!WebPInitDecoderConfig(&config)) { 27 if (!WebPInitDecoderConfig(&config)) {
29 return nil; 28 return nil;
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 * 22 *
23 * @param url The url for the image. 23 * @param url The url for the image.
24 */ 24 */
25 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url; 25 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url;
26 26
27 /** 27 /**
28 * Set the imageView `highlightedImage` with an `url` and custom options. 28 * Set the imageView `highlightedImage` with an `url` and custom options.
@@ -32,7 +32,8 @@ @@ -32,7 +32,8 @@
32 * @param url The url for the image. 32 * @param url The url for the image.
33 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 33 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
34 */ 34 */
35 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options; 35 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url
  36 + options:(SDWebImageOptions)options;
36 37
37 /** 38 /**
38 * Set the imageView `highlightedImage` with an `url`. 39 * Set the imageView `highlightedImage` with an `url`.
@@ -46,7 +47,8 @@ @@ -46,7 +47,8 @@
46 * indicating if the image was retrieved from the local cache or from the network. 47 * indicating if the image was retrieved from the local cache or from the network.
47 * The fourth parameter is the original image url. 48 * The fourth parameter is the original image url.
48 */ 49 */
49 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; 50 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url
  51 + completed:(nullable SDExternalCompletionBlock)completedBlock;
50 52
51 /** 53 /**
52 * Set the imageView `highlightedImage` with an `url` and custom options. 54 * Set the imageView `highlightedImage` with an `url` and custom options.
@@ -61,7 +63,9 @@ @@ -61,7 +63,9 @@
61 * indicating if the image was retrieved from the local cache or from the network. 63 * indicating if the image was retrieved from the local cache or from the network.
62 * The fourth parameter is the original image url. 64 * The fourth parameter is the original image url.
63 */ 65 */
64 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; 66 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url
  67 + options:(SDWebImageOptions)options
  68 + completed:(nullable SDExternalCompletionBlock)completedBlock;
65 69
66 /** 70 /**
67 * Set the imageView `highlightedImage` with an `url` and custom options. 71 * Set the imageView `highlightedImage` with an `url` and custom options.
@@ -77,7 +81,10 @@ @@ -77,7 +81,10 @@
77 * indicating if the image was retrieved from the local cache or from the network. 81 * indicating if the image was retrieved from the local cache or from the network.
78 * The fourth parameter is the original image url. 82 * The fourth parameter is the original image url.
79 */ 83 */
80 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; 84 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url
  85 + options:(SDWebImageOptions)options
  86 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  87 + completed:(nullable SDExternalCompletionBlock)completedBlock;
81 88
82 /** 89 /**
83 * Cancel the current download 90 * Cancel the current download
@@ -13,45 +13,47 @@ @@ -13,45 +13,47 @@
13 13
14 @implementation UIImageView (HighlightedWebCache) 14 @implementation UIImageView (HighlightedWebCache)
15 15
16 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url { 16 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url {
17 [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; 17 [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil];
18 } 18 }
19 19
20 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { 20 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options {
21 [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; 21 [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil];
22 } 22 }
23 23
24 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { 24 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
25 [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; 25 [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock];
26 } 26 }
27 27
28 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { 28 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {
29 [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; 29 [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock];
30 } 30 }
31 31
32 -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { 32 +- (void)sd_setHighlightedImageWithURL:(nullable NSURL *)url
  33 + options:(SDWebImageOptions)options
  34 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  35 + completed:(nullable SDExternalCompletionBlock)completedBlock {
33 [self sd_cancelCurrentHighlightedImageLoad]; 36 [self sd_cancelCurrentHighlightedImageLoad];
34 37
35 if (url) { 38 if (url) {
36 __weak __typeof(self)wself = self; 39 __weak __typeof(self)wself = self;
37 id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 40 id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
38 if (!wself) return; 41 if (!wself) return;
39 - dispatch_main_sync_safe (^  
40 - {  
41 - if (!wself) return;  
42 - if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)  
43 - {  
44 - completedBlock(image, error, cacheType, url);  
45 - return;  
46 - }  
47 - else if (image) {  
48 - wself.highlightedImage = image;  
49 - [wself setNeedsLayout];  
50 - }  
51 - if (completedBlock && finished) {  
52 - completedBlock(image, error, cacheType, url);  
53 - }  
54 - }); 42 + dispatch_main_sync_safe (^{
  43 + if (!wself) return;
  44 + if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
  45 + {
  46 + completedBlock(image, error, cacheType, url);
  47 + return;
  48 + }
  49 + else if (image) {
  50 + wself.highlightedImage = image;
  51 + [wself setNeedsLayout];
  52 + }
  53 + if (completedBlock && finished) {
  54 + completedBlock(image, error, cacheType, url);
  55 + }
  56 + });
55 }]; 57 }];
56 [self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey]; 58 [self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey];
57 } else { 59 } else {
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 * Note that because of the limitations of categories this property can get out of sync 50 * Note that because of the limitations of categories this property can get out of sync
51 * if you use setImage: directly. 51 * if you use setImage: directly.
52 */ 52 */
53 -- (NSURL *)sd_imageURL; 53 +- (nullable NSURL *)sd_imageURL;
54 54
55 /** 55 /**
56 * Set the imageView `image` with an `url`. 56 * Set the imageView `image` with an `url`.
@@ -59,7 +59,7 @@ @@ -59,7 +59,7 @@
59 * 59 *
60 * @param url The url for the image. 60 * @param url The url for the image.
61 */ 61 */
62 -- (void)sd_setImageWithURL:(NSURL *)url; 62 +- (void)sd_setImageWithURL:(nullable NSURL *)url;
63 63
64 /** 64 /**
65 * Set the imageView `image` with an `url` and a placeholder. 65 * Set the imageView `image` with an `url` and a placeholder.
@@ -70,7 +70,8 @@ @@ -70,7 +70,8 @@
70 * @param placeholder The image to be set initially, until the image request finishes. 70 * @param placeholder The image to be set initially, until the image request finishes.
71 * @see sd_setImageWithURL:placeholderImage:options: 71 * @see sd_setImageWithURL:placeholderImage:options:
72 */ 72 */
73 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 73 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  74 + placeholderImage:(nullable UIImage *)placeholder;
74 75
75 /** 76 /**
76 * Set the imageView `image` with an `url`, placeholder and custom options. 77 * Set the imageView `image` with an `url`, placeholder and custom options.
@@ -81,7 +82,9 @@ @@ -81,7 +82,9 @@
81 * @param placeholder The image to be set initially, until the image request finishes. 82 * @param placeholder The image to be set initially, until the image request finishes.
82 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 83 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
83 */ 84 */
84 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 85 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  86 + placeholderImage:(nullable UIImage *)placeholder
  87 + options:(SDWebImageOptions)options;
85 88
86 /** 89 /**
87 * Set the imageView `image` with an `url`. 90 * Set the imageView `image` with an `url`.
@@ -95,7 +98,8 @@ @@ -95,7 +98,8 @@
95 * indicating if the image was retrieved from the local cache or from the network. 98 * indicating if the image was retrieved from the local cache or from the network.
96 * The fourth parameter is the original image url. 99 * The fourth parameter is the original image url.
97 */ 100 */
98 -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; 101 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  102 + completed:(nullable SDExternalCompletionBlock)completedBlock;
99 103
100 /** 104 /**
101 * Set the imageView `image` with an `url`, placeholder. 105 * Set the imageView `image` with an `url`, placeholder.
@@ -110,7 +114,9 @@ @@ -110,7 +114,9 @@
110 * indicating if the image was retrieved from the local cache or from the network. 114 * indicating if the image was retrieved from the local cache or from the network.
111 * The fourth parameter is the original image url. 115 * The fourth parameter is the original image url.
112 */ 116 */
113 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; 117 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  118 + placeholderImage:(nullable UIImage *)placeholder
  119 + completed:(nullable SDExternalCompletionBlock)completedBlock;
114 120
115 /** 121 /**
116 * Set the imageView `image` with an `url`, placeholder and custom options. 122 * Set the imageView `image` with an `url`, placeholder and custom options.
@@ -126,7 +132,10 @@ @@ -126,7 +132,10 @@
126 * indicating if the image was retrieved from the local cache or from the network. 132 * indicating if the image was retrieved from the local cache or from the network.
127 * The fourth parameter is the original image url. 133 * The fourth parameter is the original image url.
128 */ 134 */
129 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; 135 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  136 + placeholderImage:(nullable UIImage *)placeholder
  137 + options:(SDWebImageOptions)options
  138 + completed:(nullable SDExternalCompletionBlock)completedBlock;
130 139
131 /** 140 /**
132 * Set the imageView `image` with an `url`, placeholder and custom options. 141 * Set the imageView `image` with an `url`, placeholder and custom options.
@@ -143,7 +152,11 @@ @@ -143,7 +152,11 @@
143 * indicating if the image was retrieved from the local cache or from the network. 152 * indicating if the image was retrieved from the local cache or from the network.
144 * The fourth parameter is the original image url. 153 * The fourth parameter is the original image url.
145 */ 154 */
146 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; 155 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  156 + placeholderImage:(nullable UIImage *)placeholder
  157 + options:(SDWebImageOptions)options
  158 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  159 + completed:(nullable SDExternalCompletionBlock)completedBlock;
147 160
148 /** 161 /**
149 * Set the imageView `image` with an `url` and optionally a placeholder image. 162 * Set the imageView `image` with an `url` and optionally a placeholder image.
@@ -160,14 +173,18 @@ @@ -160,14 +173,18 @@
160 * indicating if the image was retrieved from the local cache or from the network. 173 * indicating if the image was retrieved from the local cache or from the network.
161 * The fourth parameter is the original image url. 174 * The fourth parameter is the original image url.
162 */ 175 */
163 -- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; 176 +- (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url
  177 + placeholderImage:(nullable UIImage *)placeholder
  178 + options:(SDWebImageOptions)options
  179 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  180 + completed:(nullable SDExternalCompletionBlock)completedBlock;
164 181
165 /** 182 /**
166 * Download an array of images and starts them in an animation loop 183 * Download an array of images and starts them in an animation loop
167 * 184 *
168 * @param arrayOfURLs An array of NSURL 185 * @param arrayOfURLs An array of NSURL
169 */ 186 */
170 -- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs; 187 +- (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs;
171 188
172 /** 189 /**
173 * Cancel the current download 190 * Cancel the current download
@@ -17,31 +17,35 @@ static char TAG_ACTIVITY_SHOW; @@ -17,31 +17,35 @@ static char TAG_ACTIVITY_SHOW;
17 17
18 @implementation UIImageView (WebCache) 18 @implementation UIImageView (WebCache)
19 19
20 -- (void)sd_setImageWithURL:(NSURL *)url { 20 +- (void)sd_setImageWithURL:(nullable NSURL *)url {
21 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; 21 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
22 } 22 }
23 23
24 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { 24 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
25 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; 25 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
26 } 26 }
27 27
28 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 28 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
29 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; 29 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
30 } 30 }
31 31
32 -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { 32 +- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
33 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; 33 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
34 } 34 }
35 35
36 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { 36 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
37 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; 37 [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
38 } 38 }
39 39
40 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { 40 +- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {
41 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; 41 [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
42 } 42 }
43 43
44 -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { 44 +- (void)sd_setImageWithURL:(nullable NSURL *)url
  45 + placeholderImage:(nullable UIImage *)placeholder
  46 + options:(SDWebImageOptions)options
  47 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  48 + completed:(nullable SDExternalCompletionBlock)completedBlock {
45 [self sd_cancelCurrentImageLoad]; 49 [self sd_cancelCurrentImageLoad];
46 objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 50 objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
47 51
@@ -95,22 +99,26 @@ static char TAG_ACTIVITY_SHOW; @@ -95,22 +99,26 @@ static char TAG_ACTIVITY_SHOW;
95 } 99 }
96 } 100 }
97 101
98 -- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { 102 +- (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url
  103 + placeholderImage:(nullable UIImage *)placeholder
  104 + options:(SDWebImageOptions)options
  105 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  106 + completed:(nullable SDExternalCompletionBlock)completedBlock {
99 NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url]; 107 NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
100 UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key]; 108 UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key];
101 109
102 [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock]; 110 [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];
103 } 111 }
104 112
105 -- (NSURL *)sd_imageURL { 113 +- (nullable NSURL *)sd_imageURL {
106 return objc_getAssociatedObject(self, &imageURLKey); 114 return objc_getAssociatedObject(self, &imageURLKey);
107 } 115 }
108 116
109 -- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs { 117 +- (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs {
110 [self sd_cancelCurrentAnimationImagesLoad]; 118 [self sd_cancelCurrentAnimationImagesLoad];
111 __weak __typeof(self)wself = self; 119 __weak __typeof(self)wself = self;
112 120
113 - NSMutableArray *operationsArray = [[NSMutableArray alloc] init]; 121 + NSMutableArray<id<SDWebImageOperation>> *operationsArray = [[NSMutableArray alloc] init];
114 122
115 for (NSURL *logoImageURL in arrayOfURLs) { 123 for (NSURL *logoImageURL in arrayOfURLs) {
116 id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 124 id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
@@ -119,7 +127,7 @@ static char TAG_ACTIVITY_SHOW; @@ -119,7 +127,7 @@ static char TAG_ACTIVITY_SHOW;
119 __strong UIImageView *sself = wself; 127 __strong UIImageView *sself = wself;
120 [sself stopAnimating]; 128 [sself stopAnimating];
121 if (sself && image) { 129 if (sself && image) {
122 - NSMutableArray *currentImages = [[sself animationImages] mutableCopy]; 130 + NSMutableArray<UIImage *> *currentImages = [[sself animationImages] mutableCopy];
123 if (!currentImages) { 131 if (!currentImages) {
124 currentImages = [[NSMutableArray alloc] init]; 132 currentImages = [[NSMutableArray alloc] init];
125 } 133 }
@@ -134,7 +142,7 @@ static char TAG_ACTIVITY_SHOW; @@ -134,7 +142,7 @@ static char TAG_ACTIVITY_SHOW;
134 [operationsArray addObject:operation]; 142 [operationsArray addObject:operation];
135 } 143 }
136 144
137 - [self sd_setImageLoadOperation:[NSArray arrayWithArray:operationsArray] forKey:@"UIImageViewAnimationImages"]; 145 + [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];
138 } 146 }
139 147
140 - (void)sd_cancelCurrentImageLoad { 148 - (void)sd_cancelCurrentImageLoad {
@@ -17,20 +17,20 @@ @@ -17,20 +17,20 @@
17 * @param operation the operation 17 * @param operation the operation
18 * @param key key for storing the operation 18 * @param key key for storing the operation
19 */ 19 */
20 -- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key; 20 +- (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key;
21 21
22 /** 22 /**
23 * Cancel all operations for the current UIView and key 23 * Cancel all operations for the current UIView and key
24 * 24 *
25 * @param key key for identifying the operations 25 * @param key key for identifying the operations
26 */ 26 */
27 -- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key; 27 +- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key;
28 28
29 /** 29 /**
30 * Just remove the operations corresponding to the current UIView and key without cancelling them 30 * Just remove the operations corresponding to the current UIView and key without cancelling them
31 * 31 *
32 * @param key key for identifying the operations 32 * @param key key for identifying the operations
33 */ 33 */
34 -- (void)sd_removeImageLoadOperationWithKey:(NSString *)key; 34 +- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key;
35 35
36 @end 36 @end
@@ -11,10 +11,12 @@ @@ -11,10 +11,12 @@
11 11
12 static char loadOperationKey; 12 static char loadOperationKey;
13 13
  14 +typedef NSMutableDictionary<NSString *, id> SDOperationsDictionary;
  15 +
14 @implementation UIView (WebCacheOperation) 16 @implementation UIView (WebCacheOperation)
15 17
16 -- (NSMutableDictionary *)operationDictionary {  
17 - NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); 18 +- (SDOperationsDictionary *)operationDictionary {
  19 + SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
18 if (operations) { 20 if (operations) {
19 return operations; 21 return operations;
20 } 22 }
@@ -23,15 +25,17 @@ static char loadOperationKey; @@ -23,15 +25,17 @@ static char loadOperationKey;
23 return operations; 25 return operations;
24 } 26 }
25 27
26 -- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key {  
27 - [self sd_cancelImageLoadOperationWithKey:key];  
28 - NSMutableDictionary *operationDictionary = [self operationDictionary];  
29 - operationDictionary[key] = operation; 28 +- (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key {
  29 + if (key) {
  30 + [self sd_cancelImageLoadOperationWithKey:key];
  31 + SDOperationsDictionary *operationDictionary = [self operationDictionary];
  32 + operationDictionary[key] = operation;
  33 + }
30 } 34 }
31 35
32 -- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key { 36 +- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key {
33 // Cancel in progress downloader from queue 37 // Cancel in progress downloader from queue
34 - NSMutableDictionary *operationDictionary = [self operationDictionary]; 38 + SDOperationsDictionary *operationDictionary = [self operationDictionary];
35 id operations = operationDictionary[key]; 39 id operations = operationDictionary[key];
36 if (operations) { 40 if (operations) {
37 if ([operations isKindOfClass:[NSArray class]]) { 41 if ([operations isKindOfClass:[NSArray class]]) {
@@ -47,9 +51,11 @@ static char loadOperationKey; @@ -47,9 +51,11 @@ static char loadOperationKey;
47 } 51 }
48 } 52 }
49 53
50 -- (void)sd_removeImageLoadOperationWithKey:(NSString *)key {  
51 - NSMutableDictionary *operationDictionary = [self operationDictionary];  
52 - [operationDictionary removeObjectForKey:key]; 54 +- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key {
  55 + if (key) {
  56 + SDOperationsDictionary *operationDictionary = [self operationDictionary];
  57 + [operationDictionary removeObjectForKey:key];
  58 + }
53 } 59 }
54 60
55 @end 61 @end
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 <key>CFBundlePackageType</key> 15 <key>CFBundlePackageType</key>
16 <string>FMWK</string> 16 <string>FMWK</string>
17 <key>CFBundleShortVersionString</key> 17 <key>CFBundleShortVersionString</key>
18 - <string>3.8.0</string> 18 + <string>3.8.1</string>
19 <key>CFBundleSignature</key> 19 <key>CFBundleSignature</key>
20 <string>????</string> 20 <string>????</string>
21 <key>CFBundleVersion</key> 21 <key>CFBundleVersion</key>