From 9617a344082b67b760ef1e97abc0668a342d11dd Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Thu, 11 Oct 2018 17:44:18 +0800 Subject: [PATCH 1/2] Fix background download operation FIx background download Add task check when operation will deallocated && tidy code Tidy code further Tidy further --- SDWebImage/SDWebImageDownloaderOperation.m | 49 +++++++++++----------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index 427d939e..399cbd0e 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -65,6 +65,11 @@ typedef NSMutableDictionary SDCallbacksDictionary; @synthesize executing = _executing; @synthesize finished = _finished; +- (void)dealloc { + // Edge case if user call [SDWebImageDownloaderOperation start] directly and deallocated it. + [self cancel]; +} + - (nonnull instancetype)init { return [self initWithRequest:nil inSession:nil options:0]; } @@ -88,6 +93,9 @@ typedef NSMutableDictionary SDCallbacksDictionary; _unownedSession = session; _callbacksLock = dispatch_semaphore_create(1); _coderQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderOperationCoderQueue", DISPATCH_QUEUE_SERIAL); +#if SD_UIKIT + _backgroundTaskId = UIBackgroundTaskInvalid; +#endif } return self; } @@ -141,14 +149,7 @@ typedef NSMutableDictionary SDCallbacksDictionary; __weak __typeof__ (self) wself = self; UIApplication * app = [UIApplicationClass performSelector:@selector(sharedApplication)]; self.backgroundTaskId = [app beginBackgroundTaskWithExpirationHandler:^{ - __strong __typeof (wself) sself = wself; - - if (sself) { - [sself cancel]; - - [app endBackgroundTask:sself.backgroundTaskId]; - sself.backgroundTaskId = UIBackgroundTaskInvalid; - } + [wself cancel]; }]; } #endif @@ -212,18 +213,6 @@ typedef NSMutableDictionary SDCallbacksDictionary; [self done]; return; } - -#if SD_UIKIT - Class UIApplicationClass = NSClassFromString(@"UIApplication"); - if(!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) { - return; - } - if (self.backgroundTaskId != UIBackgroundTaskInvalid) { - UIApplication * app = [UIApplication performSelector:@selector(sharedApplication)]; - [app endBackgroundTask:self.backgroundTaskId]; - self.backgroundTaskId = UIBackgroundTaskInvalid; - } -#endif } - (void)cancel { @@ -262,11 +251,23 @@ typedef NSMutableDictionary SDCallbacksDictionary; SD_LOCK(self.callbacksLock); [self.callbackBlocks removeAllObjects]; SD_UNLOCK(self.callbacksLock); - self.dataTask = nil; - if (self.ownedSession) { - [self.ownedSession invalidateAndCancel]; - self.ownedSession = nil; + @synchronized (self) { + self.dataTask = nil; + + if (self.ownedSession) { + [self.ownedSession invalidateAndCancel]; + self.ownedSession = nil; + } + +#if SD_UIKIT + if (self.backgroundTaskId != UIBackgroundTaskInvalid) { + // If backgroundTaskId != UIBackgroundTaskInvalid, sharedApplication is always exist + UIApplication * app = [UIApplication performSelector:@selector(sharedApplication)]; + [app endBackgroundTask:self.backgroundTaskId]; + self.backgroundTaskId = UIBackgroundTaskInvalid; + } +#endif } } From de74bdca80679a2316befd4f0a377ab9f10cae2f Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Wed, 26 Dec 2018 20:29:09 +0800 Subject: [PATCH 2/2] Remove edge case check --- SDWebImage/SDWebImageDownloaderOperation.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index 399cbd0e..65d568bd 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -65,11 +65,6 @@ typedef NSMutableDictionary SDCallbacksDictionary; @synthesize executing = _executing; @synthesize finished = _finished; -- (void)dealloc { - // Edge case if user call [SDWebImageDownloaderOperation start] directly and deallocated it. - [self cancel]; -} - - (nonnull instancetype)init { return [self initWithRequest:nil inSession:nil options:0]; }