Ver Fonte

Merge pull request #2194 from onevcat/fix/gif-loading-crash

Use the unretained version of CGImage to avoid racing
Wei Wang há 2 anos atrás
pai
commit
e4ab3036fa
2 ficheiros alterados com 24 adições e 7 exclusões
  1. 19 0
      Sources/Image/ImageDrawing.swift
  2. 5 7
      Sources/Views/AnimatedImageView.swift

+ 19 - 0
Sources/Image/ImageDrawing.swift

@@ -567,6 +567,25 @@ extension CGImage {
         }
         return decodedImageRef
     }
+    
+    static func create(ref: CGImage) -> CGImage? {
+        guard let space = ref.colorSpace, let provider = ref.dataProvider else {
+            return nil
+        }
+        return CGImage(
+            width: ref.width,
+            height: ref.height,
+            bitsPerComponent: ref.bitsPerComponent,
+            bitsPerPixel: ref.bitsPerPixel,
+            bytesPerRow: ref.bytesPerRow,
+            space: space,
+            bitmapInfo: ref.bitmapInfo,
+            provider: provider,
+            decode: ref.decode,
+            shouldInterpolate: ref.shouldInterpolate,
+            intent: ref.renderingIntent
+        )
+    }
 }
 
 extension KingfisherWrapper where Base: KFCrossPlatformImage {

+ 5 - 7
Sources/Views/AnimatedImageView.swift

@@ -524,13 +524,10 @@ extension AnimatedImageView {
             self.maxFrameCount = count
             self.maxRepeatCount = repeatCount
             self.preloadQueue = preloadQueue
-            
-            GraphicsContext.begin(size: imageSize, scale: imageScale)
         }
         
         deinit {
             resetAnimatedFrames()
-            GraphicsContext.end()
         }
 
         /// Gets the image frame of a given index.
@@ -598,13 +595,12 @@ extension AnimatedImageView {
                 // To get a workaround, create another image ref and use that to create the final image. This leads to
                 // some performance loss, but there is little we can do.
                 // https://github.com/onevcat/Kingfisher/issues/1844
-                guard let context = GraphicsContext.current(size: imageSize, scale: imageScale, inverting: true, cgImage: cgImage),
-                      let decodedImageRef = cgImage.decoded(on: context, scale: imageScale)
-                else {
+                // https://github.com/onevcat/Kingfisher/pulls/2194
+                guard let unretainedImage = CGImage.create(ref: cgImage) else {
                     return KFCrossPlatformImage(cgImage: cgImage)
                 }
                 
-                return KFCrossPlatformImage(cgImage: decodedImageRef)
+                return KFCrossPlatformImage(cgImage: unretainedImage)
             } else {
                 let image = KFCrossPlatformImage(cgImage: cgImage)
                 if backgroundDecode {
@@ -730,3 +726,5 @@ class SafeArray<Element> {
 }
 #endif
 #endif
+
+