UIView+WebCacheOperation.m 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * This file is part of the SDWebImage package.
  3. * (c) Olivier Poitrey <rs@dailymotion.com>
  4. *
  5. * For the full copyright and license information, please view the LICENSE
  6. * file that was distributed with this source code.
  7. */
  8. #import "UIView+WebCacheOperation.h"
  9. #import "objc/runtime.h"
  10. static char loadOperationKey;
  11. // key is strong, value is weak because operation instance is retained by SDWebImageManager's runningOperations property
  12. // we should use lock to keep thread-safe because these method may not be acessed from main queue
  13. typedef NSMapTable<NSString *, id<SDWebImageOperation>> SDOperationsDictionary;
  14. @implementation UIView (WebCacheOperation)
  15. - (SDOperationsDictionary *)sd_operationDictionary {
  16. @synchronized(self) {
  17. SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
  18. if (operations) {
  19. return operations;
  20. }
  21. operations = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0];
  22. objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  23. return operations;
  24. }
  25. }
  26. - (nullable id<SDWebImageOperation>)sd_imageLoadOperationForKey:(nullable NSString *)key {
  27. id<SDWebImageOperation> operation;
  28. if (key) {
  29. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  30. @synchronized (self) {
  31. operation = [operationDictionary objectForKey:key];
  32. }
  33. }
  34. return operation;
  35. }
  36. - (void)sd_setImageLoadOperation:(nullable id<SDWebImageOperation>)operation forKey:(nullable NSString *)key {
  37. if (key) {
  38. [self sd_cancelImageLoadOperationWithKey:key];
  39. if (operation) {
  40. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  41. @synchronized (self) {
  42. [operationDictionary setObject:operation forKey:key];
  43. }
  44. }
  45. }
  46. }
  47. - (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key {
  48. if (key) {
  49. // Cancel in progress downloader from queue
  50. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  51. id<SDWebImageOperation> operation;
  52. @synchronized (self) {
  53. operation = [operationDictionary objectForKey:key];
  54. }
  55. if (operation) {
  56. if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {
  57. [operation cancel];
  58. }
  59. @synchronized (self) {
  60. [operationDictionary removeObjectForKey:key];
  61. }
  62. }
  63. }
  64. }
  65. - (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key {
  66. if (key) {
  67. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  68. @synchronized (self) {
  69. [operationDictionary removeObjectForKey:key];
  70. }
  71. }
  72. }
  73. @end