由于内存问题(使用的内存太多),我的应用程序崩溃了。当我从TableView打开足够多的对象时会发生这种情况。我在互联网上搜索了这个问题,我可以看到它可能是因为内存永远不会被释放。但是我如何发布呢?
这是我的代码。
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 :(得分:1)
我猜测占用内存的是ExerciseViewController中的运动图像。由于Swift使用ARC来管理内存,因此您希望删除对这些图像的引用(并为此而行使),以便系统可以从内存中释放它们。
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
}
由于您的exercice变量是weak
,并且没有任何内容引用它,系统现在将从内存中释放它,而不是每次用户访问新的ExerciseViewController时都会生成多个exercice副本。
答案 1 :(得分:0)
覆盖deinit函数 - 并在退出Exercise视图时检查它是否被调用。如果不是 - 我会在viewWillDisappear或Did functions中销毁计时器。