DNImageFetchOperation.m 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. //
  2. // DNImageFetchOperation.m
  3. // DNImagePicker
  4. //
  5. // Created by dingxiao on 2018/10/9.
  6. // Copyright © 2018 Dennis. All rights reserved.
  7. //
  8. #import "DNImageFetchOperation.h"
  9. #import <Photos/PHAsset.h>
  10. #import <Photos/PHImageManager.h>
  11. typedef void(^DNImageResultHandler)(UIImage *image);
  12. @interface DNImageFetchOperation ()
  13. @property (nonatomic, assign) PHImageRequestID requestID;
  14. @property (nonatomic, assign) CGSize targetSize;
  15. @property (nonatomic, assign) BOOL isHighQuality;
  16. @property (nonatomic, copy) DNImageResultHandler resultHandler;
  17. @end
  18. @implementation DNImageFetchOperation
  19. @synthesize executing = _executing;
  20. @synthesize finished = _finished;
  21. - (instancetype)initWithAsset:(PHAsset *)asset {
  22. self = [super init];
  23. if (self) {
  24. _asset = asset;
  25. _executing = NO;
  26. _finished = NO;
  27. }
  28. return self;
  29. }
  30. - (void)fetchImageWithTargetSize:(CGSize)size
  31. needHighQuality:(BOOL)isHighQuality
  32. imageResutHandler:(void (^)(UIImage * _Nonnull))handler {
  33. self.targetSize = size;
  34. self.isHighQuality = isHighQuality;
  35. self.resultHandler = handler;
  36. }
  37. - (void)start {
  38. @synchronized (self) {
  39. if (self.isCancelled) {
  40. self.finished = YES;
  41. [self reset];
  42. return;
  43. }
  44. if (!self.asset) {
  45. self.finished = YES;
  46. [self reset];
  47. return;
  48. }
  49. PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
  50. if (self.isHighQuality) {
  51. options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
  52. } else {
  53. options.resizeMode = PHImageRequestOptionsResizeModeExact;
  54. }
  55. [[PHImageManager defaultManager] requestImageForAsset:self.asset targetSize:self.targetSize contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
  56. dispatch_async(dispatch_get_main_queue(), ^{
  57. if (self.resultHandler) {
  58. self.resultHandler(result);
  59. }
  60. [self done];
  61. });
  62. }];
  63. self.executing = YES;
  64. }
  65. }
  66. - (void)cancel {
  67. @synchronized (self) {
  68. if (self.isFinished) return;
  69. [super cancel];
  70. if (self.asset && self.requestID != PHInvalidImageRequestID) {
  71. [[PHCachingImageManager defaultManager] cancelImageRequest:self.requestID];
  72. if (self.isExecuting) self.executing = NO;
  73. if (!self.isFinished) self.finished = YES;
  74. }
  75. [self reset];
  76. }
  77. }
  78. - (void)done {
  79. self.finished = YES;
  80. self.executing = NO;
  81. [self reset];
  82. }
  83. - (void)reset {
  84. self.asset = nil;
  85. }
  86. - (void)setFinished:(BOOL)finished {
  87. [self willChangeValueForKey:@"isFinished"];
  88. _finished = finished;
  89. [self didChangeValueForKey:@"isFinished"];
  90. }
  91. - (void)setExecuting:(BOOL)executing {
  92. [self willChangeValueForKey:@"isExecuting"];
  93. _executing = executing;
  94. [self didChangeValueForKey:@"isExecuting"];
  95. }
  96. - (BOOL)isConcurrent {
  97. return YES;
  98. }
  99. @end