Bläddra i källkod

Crash sample for high res images

onevcat 7 år sedan
förälder
incheckning
10df15802a

+ 28 - 8
Demo/Demo/Kingfisher-Demo/ViewControllers/HighResolutionCollectionViewController.swift

@@ -43,18 +43,38 @@ class HighResolutionCollectionViewController: UICollectionViewController {
 
 
     override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-        return ImageLoader.highResolutionImageURLs.count
+        return ImageLoader.highResolutionImageURLs.count * 10
     }
 
-    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ImageCollectionViewCell
-        cell.cellImageView.kf.setImage(
-            with: ImageLoader.highResolutionImageURLs[indexPath.row],
+    override func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
+    {
+        (cell as! ImageCollectionViewCell).cellImageView.kf.cancelDownloadTask()
+    }
+    
+    override func collectionView(
+        _ collectionView: UICollectionView,
+        willDisplay cell: UICollectionViewCell,
+        forItemAt indexPath: IndexPath)
+    {
+        let url = ImageLoader.highResolutionImageURLs[indexPath.row % 10]
+        // Use different cache key to prevent reuse the same image. It is just for
+        // this demo. Normally you can just use the URL to set image.
+        let resource = ImageResource(downloadURL: url, cacheKey: "\(url.absoluteString)-\(indexPath.row)")
+        
+        // This should crash most devices due to memory pressure.
+        // (cell as! ImageCollectionViewCell).cellImageView.kf.setImage(with: resource)
+        
+        // This would survive!
+        (cell as! ImageCollectionViewCell).cellImageView.kf.setImage(
+            with: resource,
             options: [
                 .processor(DownsamplingImageProcessor(size: CGSize(width: 250, height: 250))),
-                .scaleFactor(UIScreen.main.scale),
                 .cacheOriginalImage
-            ])
+        ])
+    }
+    
+    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
         return cell
     }
     
@@ -62,7 +82,7 @@ class HighResolutionCollectionViewController: UICollectionViewController {
         if segue.identifier == "showImage" {
             let vc = segue.destination as! DetailImageViewController
             let index = collectionView.indexPathsForSelectedItems![0].row
-            vc.imageURL =  ImageLoader.highResolutionImageURLs[index]
+            vc.imageURL =  ImageLoader.highResolutionImageURLs[index % 10]
         }
     }
 }

+ 3 - 4
Sources/Networking/ImageDataProcessor.swift

@@ -26,6 +26,8 @@
 
 import Foundation
 
+let processQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageDownloader.Process")
+
 // Handles image processing work on an own process queue.
 class ImageDataProcessor {
     let data: Data
@@ -35,10 +37,7 @@ class ImageDataProcessor {
     // queue settings in each option...
     let onImageProcessed = Delegate<(Result<Image, KingfisherError>, SessionDataTask.TaskCallback), Void>()
 
-    private let processQueue: DispatchQueue
-
-    init(name: String, data: Data, callbacks: [SessionDataTask.TaskCallback]) {
-        self.processQueue = DispatchQueue(label: "com.onevcat.Kingfisher.ImageDownloader.Process.\(name)")
+    init(data: Data, callbacks: [SessionDataTask.TaskCallback]) {
         self.data = data
         self.callbacks = callbacks
     }

+ 1 - 1
Sources/Networking/ImageDownloader.swift

@@ -240,7 +240,7 @@ open class ImageDownloader {
             switch result {
             // Download finished. Now process the data to an image.
             case .success(let (data, response)):
-                let prosessor = ImageDataProcessor(name: self.name, data: data, callbacks: callbacks)
+                let prosessor = ImageDataProcessor(data: data, callbacks: callbacks)
                 prosessor.onImageProcessed.delegate(on: self) { (self, result) in
                     // `onImageProcessed` will be called for `callbacks.count` times, with each
                     // `SessionDataTask.TaskCallback` as the input parameter.