Zander
Zander

Reputation: 414

TableView lagging too much and taking up too much memory Swift

I have an Application that uses a UITableView inside of a UIViewController, and the way each cell gets formed is, the information about the Issues, or Blog Posts, are stored in CoreData after they are downloaded. But when I ran the instruments tool, I found out that everytime you scroll down or up it fetches that CoreData. Even if the cell was already initialized, so this combined with apparently NSDate takes up a look of Memory as well. The program is taking up around 40m of ram and around 60% of CPU when you scroll down! And I have looked for answers of how to only initialize it once but could find it anywhere. Here it my TableView code:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("tableviewcell", forIndexPath: indexPath) as! BlogTableViewCell

    let sortedPosts = SortPosts()
    let realresults = sortedPosts.sortData()




    if realresults.count > 0 {
        println(cell)
        let date = realresults[indexPath.row].valueForKey("date") as? NSDate
        let numberOfTime = PostDateFormatter().getFormattedDate(date!)
        let content = realresults[indexPath.row].valueForKey("content") as! String
        let title = realresults[indexPath.row].valueForKey("title") as! String

        cell.configureCell(Post(title: title.html2String, author: realresults[indexPath.row].valueForKey("author") as! String, date: numberOfTime, content: content.html2String))
        tableView.hidden = false
        self.view.backgroundColor = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 255.0/255.0)
        myIndicator.stopAnimating()
        myIndicator.hidden = true
        }
    else {
        if PostServices().isConnectedToNetwork() {
            println("Error 0 results returned......")
            self.tableView.reloadData()
        }

    }

    return cell
}

and here it SortPosts:

class SortPosts {
func sortData() -> NSArray {
    var jsonin = NSArray()

    let formatter = NSDateFormatter()
    formatter.dateFormat = "Y-MM-dd\'T\'HH:mm:ss"

    var managedObjectContext : NSManagedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!

    var request = NSFetchRequest(entityName: "Post")
    request.returnsObjectsAsFaults = false

    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    request.sortDescriptors = [sortDescriptor]

    var results : NSArray = managedObjectContext.executeFetchRequest(request, error: nil)!

    return results



}

}

And here is PostDateFormatter:

class PostDateFormatter {
func getFormattedDate(date : NSDate) -> String {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
let dateInShortFormat = dateFormatter.stringFromDate(date)

let inter = date.timeIntervalSinceNow

var seconds = Int(abs(inter))
var minutes = seconds/60
var hours = minutes/60
var days = hours/24
var weeks = days/7


if seconds < 60 {
return "\(seconds)s"
} else if minutes < 60 {
return "\(minutes)m"
} else if hours < 24 {
return "\(hours)h"
} else if days < 7 {
return "\(days)d"
} else if weeks <= 8 {
return "\(weeks)w"
} else if weeks > 8 {
return "\(dateInShortFormat)"
}
    return "Something went wrong with date formatting"
}

}

Upvotes: 3

Views: 1683

Answers (3)

NIMO
NIMO

Reputation: 33

If you're up for the challenge I would suggest to use: asyncdisplaykit.

I believe it would help your memory issues. It was originally built to make Facebook's Paper possible.

http://asyncdisplaykit.org/

Upvotes: 0

MDB983
MDB983

Reputation: 2454

You do realize that for each cell you're calling;

   let sortedPosts = SortPosts()
   let realresults = sortedPosts.sortData() 

it would make more sense to init all your data outside of your tableView, or certainly at some point other than cellForRowAtIndexPath.

Build an Array or Dictionary of items elsewhere, then simply reference the items in the array in your cellForRowAtIndexPath. This way, you're only accessing core data once.

Upvotes: 3

pbush25
pbush25

Reputation: 5258

What you're saying in your question describes exactly how TableViews work. Each cell is dequeued only when it will be visible on the screen. Otherwise, there are no other cells in memory, and when new cells are displayed, they have to be dequeued and thus require hitting the database and the CPU for information and drawing whenever they are displayed.

Upvotes: 0

Related Questions