SDWebImage: AVMetadataItemValueRequest & SDWebImageManager.load hang

New Issue Checklist

Issue Info

Info Value
Platform Name ios
Platform Version 14.0 - 16.2
SDWebImage Version 5.12.1
Integration Method cocoapods
Xcode Version 14.2
Repro rate all the time (100%)
Repro with our demo prj don’t know yet
Demo project link none

Issue Description and Steps

  • iOS application with AVKit, SDWebImage (cocoapods)
  • Lazy load artwork like that:
extension AVMetadataItem {
    static func artwork(url: URL, placeholder: UIImage?) -> AVMetadataItem {
        let art = AVMutableMetadataItem()
        art.identifier = .commonIdentifierArtwork
        art.dataType = kCMMetadataBaseDataType_PNG as String
        art.extendedLanguageTag = "und"

        return AVMetadataItem(propertiesOf: art) { request in 
              SDWebImageManager.shared
                .loadImage(with: url, context: [:], progress: nil) { image, _, error, _, _, _ in
                     // no call here at all, hang application before this callback
                    let cover: UIImage?

                    if let image = image {
                        cover = image

                    } else {
                        cover = placeholder
                    }

                    guard let data = cover?.pngData() else {
                        request.respond(error: CustomError.loadImageFailed)
                        return
                    }

                    request.respond(value: data as NSData)
                }
        }
}

I found some place in code there is hang started in file SDImageCache.m:

if (doneBlock) {
                if (shouldQueryDiskSync) {
                    doneBlock(diskImage, diskData, SDImageCacheTypeDisk);
                } else {
                    dispatch_async(dispatch_get_main_queue(), ^{ // <<< HERE
                        doneBlock(diskImage, diskData, SDImageCacheTypeDisk);
                    });
                }
            }

This hang happen only when call load image in AVMetadataItem function for lazy load, nothing hangs when load by URLSession.shared Can’t yet understand any reason for that 😦

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 20 (14 by maintainers)

Most upvoted comments

Yes. SDWebImage currently hardcode to callback to main queue, this cause issue.

URLSession’s callback queue is control by you. By defaults is just callback in a random global queue, if you don’t dispatch it into main queue (which is already been block by AVKit), nothing worng happended.

I think this is because that the SDImageCache’s callback queue is main queue.

However, the main queue is blocked by AVFCore -[AVLazyValueLoadingMetadataItem _waitForLoadingOfValueDependentKey:]:

The caller queue isAVFCore __84-[AVLazyValueLoadingMetadataItem loadValuesAsynchronouslyForKeys:completionHandler:]_block_invoke_3 (), and enqueue into SDImageCache (which is queue 2, but this actually does not effect the result)

Did you get it ?

The problem occurs because:

  1. AVKit main queue wait for queue 8
  2. queue 8 call SDWebImageManager to query cache
  3. query cache finished, callback to submit block to main queue
  4. dead here, becaue main queue wait queue 8 wait main queue
截屏2022-12-30 21 21 10 截屏2022-12-30 21 21 17