search

Home  >  Q&A  >  body text

ios - 关于sdwebimage的疑问

刚在看sdwebimage的源码,在SDWebImageDownloaderOperation这个类的start方法里,

- (void)start {
    @synchronized (self) {
        if (self.isCancelled) {
            self.finished = YES;
            [self reset];
            return;
        }

#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
        if ([self shouldContinueWhenAppEntersBackground]) {
            __weak __typeof__ (self) wself = self;
            self.backgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
                __strong __typeof (wself) sself = wself;

                if (sself) {
                    [sself cancel];

                    [[UIApplication sharedApplication] endBackgroundTask:sself.backgroundTaskId];
                    sself.backgroundTaskId = UIBackgroundTaskInvalid;
                }
            }];
        }
#endif

        self.executing = YES;
        self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];
        self.thread = [NSThread currentThread];
    }

    [self.connection start];

    if (self.connection) {
        if (self.progressBlock) {
            self.progressBlock(0, NSURLResponseUnknownLength);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self];
        });

        if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_5_1) {
            // Make sure to run the runloop in our background thread so it can process downloaded data
            // Note: we use a timeout to work around an issue with NSURLConnection cancel under iOS 5
            //       not waking up the runloop, leading to dead threads (see https://github.com/rs/SDWebImage/issues/466)
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false);
        }
        else {
            CFRunLoopRun();
        }

        if (!self.isFinished) {
            [self.connection cancel];
            [self connection:self.connection didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:@{NSURLErrorFailingURLErrorKey : self.request.URL}]];
        }
    }
    else {
        if (self.completedBlock) {
            self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}], YES);
        }
    }

#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
    if (self.backgroundTaskId != UIBackgroundTaskInvalid) {
        [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskId];
        self.backgroundTaskId = UIBackgroundTaskInvalid;
    }
#endif
}
 [self.connection start];

开启了connection, 然后判断connection是否存在,如果存在的话,里面有一段

 if (!self.isFinished) {
            [self.connection cancel];
            [self connection:self.connection didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:@{NSURLErrorFailingURLErrorKey : self.request.URL}]];
        }

这一段我就不理解了,如果它没有结束,就取消connection。刚刚开启connection,现在就取消connection?而且是不结束的时候取消,这是什么意思?

大家讲道理大家讲道理2892 days ago340

reply all(3)I'll reply

  • PHPz

    PHPz2017-04-18 09:07:56

    It can be understood that before the download has a result (normal completion, or an error occurs), the code will always be blocked in CFRunLoopRun() or CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false). This means that after calling start, the download will always be in progress. In progress, this blocking will not be released until the download is completed or an error occurs (CFRunLoopStop will be called in both cases).

    At this time, if it is found that isFinished is still NO, it means that it has timed out, cancel the current connection, and throw a timeout error.

    reply
    0
  • 怪我咯

    怪我咯2017-04-18 09:07:56

    beginBackgroundTaskWithExpirationHandler: It will be reached when you enter the background and time out. When it times out, you should cancel the connection to avoid occupying resources

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-18 09:07:56

    The core code is here

    CFRunLoopRun();
    

    It blocks the current thread indefinitely until CFRunLoopStop is called unknown

    reply
    0
  • Cancelreply