2016-05-28 14 views
0

Meine App stürzt wegen eines Speicherproblems ab (zu viel Speicher wird verwendet). Das passiert, wenn ich genügend Objekte aus TableView öffne. Ich habe das Internet nach dem Problem gesucht, und ich kann es sehen, weil der Speicher nie veröffentlicht wird. Aber wie kann ich es veröffentlichen?Speicherproblem von UITable

Hier ist mein Code.

TableExerciseViewController

class TableExercisesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

var choosenCellIndex = 0 
var filteredExercises = [Exercise]() 

let searchController = UISearchController(searchResultsController: nil) 

@IBOutlet weak var searchBar: UISearchBar! 

@IBOutlet weak var tableView: UITableView! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    searchController.searchResultsUpdater = self 
    searchController.dimsBackgroundDuringPresentation = false 

    searchController.searchBar.placeholder = "Look up an exercise..." 

    definesPresentationContext = true 
    tableView.tableHeaderView = searchController.searchBar 
} 

override func viewDidAppear(animated: Bool) { 
    if let row = tableView.indexPathForSelectedRow { 
     self.tableView.deselectRowAtIndexPath(row, animated: false) 
    } 
} 


override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 




func filterContentForSearchText(searchText: String, scope: String = "All") { 
    filteredExercises = ExerciseManager.sharedInstance.getExercises().filter { 
     exercise in return exercise.name.lowercaseString.containsString(searchText.lowercaseString) 
    } 

    tableView.reloadData() 
} 


//Returns the size of the arraylist 
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 


    if searchController.active && searchController.searchBar.text != "" { 
     return filteredExercises.count 
    } 
    return ExerciseManager.sharedInstance.getExercises().count 
} 

//Returns the selected Cell 
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCellWithIdentifier("Exercise Cell", forIndexPath: indexPath) as! ExerciseCustomCell 
    let exercise: Exercise 
    if searchController.active && searchController.searchBar.text != "" { 
     exercise = filteredExercises[indexPath.row] 
    } else { 
     exercise = ExerciseManager.sharedInstance.getExercises()[indexPath.row] 
    } 

    cell.imgExercise?.image = exercise.exerciseImage1 
    cell.lblExerciseName?.text = exercise.name 
    cell.lblExerciseMuscleGroup?.text = exercise.muscle 
    cell.lblExerciseTools?.text = "Equipment: \(exercise.tool)" 

    return cell 
} 

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return 1 
} 


//Sends the data through the selected identifier 
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    choosenCellIndex = indexPath.row 

    // Start segue with index of cell clicked 
    self.performSegueWithIdentifier("Show Exercise", sender: self) 

} 

//Prepares the data for the segue and the next viewcontroller 
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 

    // get a reference to the second view controller 
    let exerciseViewController = segue.destinationViewController as! ExerciseViewController 

    // set a variable in the second view controller with the data to pass 
    if searchController.active && searchController.searchBar.text != "" { 
     exerciseViewController.exercise = filteredExercises[choosenCellIndex] 
    } else { 
     exerciseViewController.exercise = ExerciseManager.sharedInstance.getExercises()[choosenCellIndex] 
    } 

} 

deinit { 
    debugPrint("TableExerciseView deinitialized...") 
} 

} 

extension TableExercisesViewController: UISearchResultsUpdating { 
func updateSearchResultsForSearchController(searchController: UISearchController) { 
    filterContentForSearchText(searchController.searchBar.text!) 
} 

ExerciseViewController

class ExerciseViewController: UIViewController { 
weak var exercise: Exercise? 
var receivedCellIndex = 0 

@IBOutlet weak var scrollView: UIScrollView! 

@IBOutlet weak var lblExerciseName: UILabel! 

@IBOutlet weak var lblExerciseMuscleGroup: UILabel! 

@IBOutlet weak var lblStartDescription: UILabel! 

@IBOutlet weak var lblLastDescription: UILabel! 


@IBOutlet weak var imgExerciseAnimation: UIImageView! 

@IBOutlet weak var imgExerciseStartPosition: UIImageView! 

@IBOutlet weak var imgExerciseLastPosition: UIImageView! 

var timer = NSTimer() 
var counter = 1 


override func viewDidLoad() { 
    super.viewDidLoad() 

    //Sets the color of the back button in navigation bar 
    self.navigationController!.navigationBar.tintColor = UIColor.whiteColor(); 

    //Sets the labels 
    lblExerciseName.text = exercise?.name 
    lblExerciseMuscleGroup.text = exercise!.muscle 
    lblStartDescription.text = "1. \(exercise!.startDescription)" 
    lblLastDescription.text = "2. \(exercise!.lastDescription)" 


    //Sets the antimation and the images 
    imgExerciseAnimation.image = exercise?.exerciseImage1 
    imgExerciseStartPosition.image = exercise?.exerciseImage1 
    imgExerciseLastPosition.image = exercise?.exerciseImage2 

    //Timer 
    self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(ExerciseViewController.demonstrateExercise), userInfo: nil, repeats: true) 

} 

override func viewWillDisappear(animated: Bool) { 
    super.viewWillDisappear(animated) 
    self.timer.invalidate() 
} 

func demonstrateExercise() { 
    if counter == 1 { 
     imgExerciseAnimation.image = exercise?.exerciseImage2 
     counter += 1 
    } else { 
     counter = 1 
     imgExerciseAnimation.image = exercise?.exerciseImage1 
    } 
} 
} 
+0

durch offene genug od objekt meinst du didSelectRow event? – Alok

+0

Ja, wo es die Überfahrt passiert. @ Alok – Grumme

+0

Wie groß ist jedes Bild? – Xcoder

Antwort

1

Ich vermute, dass das, was die Erinnerung die Übung Bilder in Ihrem ExerciseViewController sind Aufnahme ist. Da Swift ARC verwendet, um den Speicher zu verwalten, sollten Sie Verweise auf diese Bilder (und Übungen) entfernen, damit das System sie aus dem Speicher freigeben kann.

override func viewDidDisappear(animated: Bool) { 
    lblExerciseName.text = nil 
    lblExerciseMuscleGroup.text = nil 
    lblStartDescription.text = nil 
    lblLastDescription.text = nil 

    imgExerciseAnimation.image = nil 
    imgExerciseStartPosition.image = nil 
    imgExerciseLastPosition.image = nil 
} 

Da IhrDeterm exercice Variable ist weak, und nichts verweist darauf, werden das System nun frei, um es aus dem Speicher statt mit mehreren Kopien von exercices bauen jedes Mal, wenn der Benutzer einen neuen ExerciseViewController besucht werden.

+0

Hallo @ JeremyRea. Das Problem besteht nach der Aktualisierung der ViewDidDisappear-Funktion weiterhin. Haben Sie weitere Vorschläge oder Ideen? – Grumme

+0

@Jakob Ändert das Hinzufügen von 'Übung = Null 'irgendetwas? –

0

Die Deinit-Funktion außer Kraft setzen - und prüfen, ob sie aufgerufen wird, wenn Sie die Übungsansicht verlassen. Wenn nicht - ich würde den Timer in ViewWillDisappear oder Did Funktionen zerstören.

+0

Jedes Mal, wenn ich die Trainingsansicht verlasse, wird die Deinit-Funktion aufgerufen. – Grumme

+0

Ich habe mit und ohne Timer getestet - aber das Problem besteht immer noch. Im Moment ist meine viewDidDisappear Funktion wie folgt aussehen: 'super.viewWillDisappear (animiert) lblExerciseName.text = nil lblExerciseMuscleGroup.text = nil lblStartDescription.text = nil lblLastDescription.text = nil imgExerciseAnimation.image = null imgExerciseStartPosition.image = null imgExerciseLastPosition.image = null self.timer.invalidate() ' – Grumme