Latheesan
Latheesan

Reputation: 24116

Attempting to load the view of a view controller while it is deallocating

I am learning to implement TableView with Search Bar and data filtering. So, I have the following in my storyboard:

enter image description here

My UITableViewController is connected to the following SearchTableViewController.swift class like this:

import UIKit

class SearchTableViewController: UITableViewController, UISearchResultsUpdating {

    // table view controller properties
    let appleProducts = ["Mac", "iPhone", "Apple Watch", "iMac", "iPad"]
    var filteredAppleProducts = [String]()
    var resultSearchController = UISearchController()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Configure result search controller
        self.resultSearchController = UISearchController(searchResultsController: nil)
        self.resultSearchController.searchResultsUpdater = self
        self.resultSearchController.dimsBackgroundDuringPresentation = false
        self.resultSearchController.searchBar.sizeToFit()
        self.resultSearchController.searchBar.placeholder = "Search Products"
        self.tableView.tableHeaderView = self.resultSearchController.searchBar
        self.tableView.reloadData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // MARK: - Table view data source

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if (self.resultSearchController.active) {
            return self.filteredAppleProducts.count
        } else {
            return self.appleProducts.count
        }
    }

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

        if (self.resultSearchController.active) {
            cell.textLabel?.text = self.filteredAppleProducts[indexPath.row]
        } else {
            cell.textLabel?.text = self.appleProducts[indexPath.row]
        }

        return cell
    }

    func updateSearchResultsForSearchController(searchController: UISearchController) {
        self.filteredAppleProducts.removeAll(keepCapacity: false)
        let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
        let resultArray = (self.appleProducts as NSArray).filteredArrayUsingPredicate(searchPredicate)
        self.filteredAppleProducts = resultArray as! [String]
        self.tableView.reloadData()
    }

}

This runs fine and filtering is working as expected:

enter image description here

However, when the app is running in the simulator, I get the following warning in the debug window:

2015-09-07 00:02:46.116 TableViewSearch[2415:68217] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior ()

Any ideas how to fix this?

Upvotes: 3

Views: 8597

Answers (2)

MichikoP
MichikoP

Reputation: 73

I spent all day to understand this problem too... Some said it's related to Navigation Controller issue and others said it's a glitch. Although this may not be the correct answer, hope I can give some hint. If you think it's not a correct approach, let me know. Thanks. My case is as follows instead (because of a different design, I think.)

var resultSearchController: UISearchController!()

Then, I had to add below.

self.resultSearchController.loadViewIfNeeded()

Upvotes: 6

Apoorv Mote
Apoorv Mote

Reputation: 523

Just change following line

var resultSearchController = UISearchController()

to following line

var resultSearchController:UISearchController!

Your rest of the code is ok. Only that one change is required.

If you want to see detailed explanation then check my tutorial on UISearchController

Upvotes: 1

Related Questions