mantov1
mantov1

Reputation: 117

UITableView with many images high memory usage

Hi i am using MKMapSnapshotter to generate map images and cache them using SDWebImage. The map images will be displayed in each uitableview cell.

The problem i'm having is for about 30 uitableview cells the memory used is 130 MB, if i don't use map images the memory used is 25 MB, and finally using map images but without caching(as in generating the map image every time a cell is displayed) the memory used is 50 MB.

How can i reduce the memory usage? Or how can i store the images so they take up less memory space? Any help would be appreciated. The code i have is below.

At the top of the class:

var imageCache: SDImageCache!
var mySnapOptions: MKMapSnapshotOptions!
let regionRadius: CLLocationDistance = 300
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)

In viewDidLoad():

imageCache = SDImageCache(namespace: "myNamespace")
mySnapOptions = MKMapSnapshotOptions()
mySnapOptions.scale = UIScreen.mainScreen().scale

And in cellForRow:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> TableViewCell? {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! TableViewCell

    if let post = object {
        cell.mapImageView.image = UIImage(named: "MapPlaceholder")

        let tempLoc = post["location"] as! PFGeoPoint
        let loc = CLLocation(latitude: tempLoc.latitude, longitude: tempLoc.longitude)

        imageCache.queryDiskCacheForKey(post.objectId, done: {(image: UIImage?, cacheType: SDImageCacheType!) in
            if let cachedImage = image {
                cell.mapImageView.image = cachedImage
            }else {
                cell.mapPinImageView.hidden = true
                cell.mapActivityIndicator.startAnimating()

                dispatch_async(self.queue) { () -> Void in
                    self.mySnapOptions.region = MKCoordinateRegionMakeWithDistance(loc.coordinate,
                        self.regionRadius * 2.0, self.regionRadius * 2.0)
                    self.mySnapOptions.size = (cell.mapImageView.image?.size)!

                    MKMapSnapshotter(options: self.mySnapOptions).startWithCompletionHandler { snapshot, error in
                        guard let snapshot = snapshot else {
                            print("Snapshot error: \(error)")
                            return
                        }
                        self.imageCache.storeImage(snapshot.image, forKey: post.objectId, toDisk: true)
                        dispatch_async(dispatch_get_main_queue(), {
                            cell.mapActivityIndicator.stopAnimating()
                            cell.mapImageView.image = snapshot.image
                            cell.mapPinImageView.hidden = false
                        })
                    }

                    //
                }
            }
        })


    }
    return cell
}

Upvotes: 2

Views: 611

Answers (1)

mantov1
mantov1

Reputation: 117

I ended up using a different caching framework. FastImageCache, allowed me to achieve the desired results with great scrolling performance, and low memory usage, as the images are not stored in memory but rather on disk (this is how FastImageCache works).

Upvotes: 1

Related Questions