UIView+WebCacheOperation.m 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. // key is strong, value is weak because operation instance is retained by SDWebImageManager's runningOperations property
  11. // we should use lock to keep thread-safe because these method may not be accessed from main queue
  12. typedef NSMapTable<NSString *, id<SDWebImageOperation>> SDOperationsDictionary;
  13. @implementation UIView (WebCacheOperation)
  14. - (SDOperationsDictionary *)sd_operationDictionary {
  15. @synchronized(self) {
  16. SDOperationsDictionary *operations = objc_getAssociatedObject(self, @selector(sd_operationDictionary));
  17. if (operations) {
  18. return operations;
  19. }
  20. operations = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsWeakMemory capacity:0];
  21. objc_setAssociatedObject(self, @selector(sd_operationDictionary), operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  22. return operations;
  23. }
  24. }
  25. - (nullable id<SDWebImageOperation>)sd_imageLoadOperationForKey:(nullable NSString *)key {
  26. id<SDWebImageOperation> operation;
  27. if (key) {
  28. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  29. @synchronized (self) {
  30. operation = [operationDictionary objectForKey:key];
  31. }
  32. }
  33. return operation;
  34. }
  35. - (void)sd_setImageLoadOperation:(nullable id<SDWebImageOperation>)operation forKey:(nullable NSString *)key {
  36. if (key) {
  37. [self sd_cancelImageLoadOperationWithKey:key];
  38. if (operation) {
  39. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  40. @synchronized (self) {
  41. [operationDictionary setObject:operation forKey:key];
  42. }
  43. }
  44. }
  45. }
  46. - (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key {
  47. if (key) {
  48. // Cancel in progress downloader from queue
  49. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  50. id<SDWebImageOperation> operation;
  51. @synchronized (self) {
  52. operation = [operationDictionary objectForKey:key];
  53. }
  54. if (operation) {
  55. if ([operation respondsToSelector:@selector(cancel)]) {
  56. [operation cancel];
  57. }
  58. @synchronized (self) {
  59. [operationDictionary removeObjectForKey:key];
  60. }
  61. }
  62. }
  63. }
  64. - (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key {
  65. if (key) {
  66. SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
  67. @synchronized (self) {
  68. [operationDictionary removeObjectForKey:key];
  69. }
  70. }
  71. }
  72. @end