Search code examples
iosswiftmemory-leaksphasset

Memory leak in getting images from gallery to my application


I have this function. This function initializes all the media files for gallery view.

func initMediaFiles() {
    var assets: [PHAsset] = []
    let options = PHFetchOptions()
    options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

options.fetchLimit = 1000
    let results = PHAsset.fetchAssets(with: .image, options: options)
    results.enumerateObjects({ (object, _, _) in
        if let asset = object as? PHAsset {
            assets.append(asset)

        }
    })        
 SCPAsset.imageManager.startCachingImages(for: assets, targetSize: CGSize(width: 110.0, height: 147.0),contentMode: .aspectFill,  options: nil)
    for asset in assets {
        let scpAsset = SCPAsset(initWithPHAsset: asset)
        scpAsset.inspectionUUID = self.inspectionId!
        self.mediaAssets.append(scpAsset)
    }

}

I am not able to see why I am getting like 10,000 memory leak every time i load the gallery view.


Solution

  • Here's something I've done in a project that might help:

    Some properties:

     let requestOptions = PHImageRequestOptions()
        let fetchOptions = PHFetchOptions()
        let cachingImageManager = PHCachingImageManager()
        var assets: [PHAsset] = [] {
            willSet {
                cachingImageManager.stopCachingImagesForAllAssets()
            }
    
            didSet {
                cachingImageManager.startCachingImagesForAssets(assets,
                    targetSize: PHImageManagerMaximumSize,
                    contentMode: .AspectFit,
                    options: self.requestOptions
                )
            }
        }
    
    
        func fetchPhotos() {
            requestOptions.resizeMode = PHImageRequestOptionsResizeMode.Exact
            requestOptions.version = .Current
            requestOptions.deliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat
            requestOptions.synchronous = true
    
            fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: false)]
            if #available(iOS 9.0, *) {
                fetchOptions.fetchLimit = 50
            } else {
    
                // Fallback on earlier versions
            }
    
            fetchResults = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions)
            guard let fetchResults = fetchResults else {
                print("No PHAssets")
                return
            }
            dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [weak self] in
                fetchResults.enumerateObjectsUsingBlock{ object, index, stop in
                    let asset = object as! PHAsset
                    self?.assets.append(asset)
                }
                dispatch_async(dispatch_get_main_queue()) {
                    self?.photoCollectionView.reloadData()
                }
            }
        }