Ich habe Code, der eine UISearchController' in my UIVIew's
viewDidLoad` erstellt.
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.searchBar.delegate = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.hidesNavigationBarDuringPresentation = false //prevent search bar from moving
controller.searchBar.placeholder = "Search for song"
self.myTableView.tableHeaderView = controller.searchBar
return controller
})()
Unmittelbar nach Abschluss dieser Schließung wird diese Warnung in der Konsole angezeigt:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UISearchController: 0x154d39700>)
Ich verstehe nicht, was ich falsch mache. Diese ähnliche Frage ist nicht wirklich meine Situation (zumindest glaube ich das nicht). Was ist los?
ios
swift
uisearchcontroller
MortalMan
quelle
quelle
viewDidLoad()
. Empfehlen Sie a) die vollständige VC-Quellenliste einzuschließen und b) sicherzustellen, dass der Fehler tatsächlich dort auftritt, wo und wann Sie glauben, dass er vorliegt.})()
und nachher einen Haltepunkt gesetzt})()
. Der Fehler wird ausgelöst, nachdem der Abschluss beendet ist. Ich habe eineUIViewController
, keinetableViewController
.Antworten:
Die Ansicht von UISearchController muss vor der Freigabe aus der Übersicht entfernt werden. (denke, es ist ein Fehler)
Ziel c...
-(void)dealloc { [searchController.view removeFromSuperview]; // It works! }
Swift 3 ...
deinit { self.searchController.view.removeFromSuperview() }
Ich hatte ein paar Wochen mit diesem Problem zu kämpfen. ^^
quelle
UISearchControler
ich zugeteilt hatte-viewDidLoad
. Es ist definitiv ein Fehler - wenn dieUISearchController
Zuordnung aufgehoben wird, bevor die Ansicht geladen wird, wird diese Warnung angezeigt. Wenn ich auf das Suchfeld tippe (wodurch die Ansicht geladen wird), wird es nicht angezeigt. Also in meinemdealloc
rufe ich an[self.searchController loadViewIfNeeded]
(neu in iOS 9),if #available(iOS 9.0, *) { self.searchController?.loadViewIfNeeded() }
[self.searchController loadViewIfNeeded];
(Obj-C) die Antwort, die das Problem in meinem Code gelöst hat.Gelöst! Es war eine einfache Lösung. Ich habe diesen Code geändert
class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate { var resultSearchController = UISearchController()
dazu:
class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate { var resultSearchController: UISearchController!
Dies behebt das Problem.
quelle
Hier ist die Swift-Version, die für mich funktioniert hat (ähnlich der Antwort von JJH):
deinit{ if let superView = resultSearchController.view.superview { superView.removeFromSuperview() } }
quelle
if let
da.removeFromSuperView()
es nichts tun wird, wennsuperview == nil
class SampleClass: UITableViewController, UISearchBarDelegate { private let searchController = UISearchController(searchResultsController: nil) override func viewDidLoad() { super.viewDidLoad() searchController.loadViewIfNeeded() // Add this line before accessing searchController } }
quelle
Ein paar Lösungen zusammenhacken Ich habe es geschafft, meine zum Laufen zu bringen, indem ich Zeilen zu viewDidLoad hinzugefügt habe, bevor ich den UISearchController vollständig eingerichtet habe:
override func viewDidLoad() { super.viewDidLoad() self.navigationItem.rightBarButtonItem = self.editButtonItem() if #available(iOS 9.0, *) { self.resultSearchController.loadViewIfNeeded()// iOS 9 } else { // Fallback on earlier versions let _ = self.resultSearchController.view // iOS 8 } self.resultSearchController = ({ let controller = UISearchController(searchResultsController: nil) controller.searchResultsUpdater = self controller.dimsBackgroundDuringPresentation = false controller.searchBar.sizeToFit() self.tableView.tableHeaderView = controller.searchBar return controller })() self.tableView.reloadData() }
quelle
self.searchController = ({ let controller = UISearchController(searchResultsController: nil) controller.searchResultsUpdater = self controller.dimsBackgroundDuringPresentation = false controller.searchBar.delegate = self definesPresentationContext = true controller.searchBar.sizeToFit() return controller })()
dannself.searchController.loadViewIfNeeded()
In Swift2 wurde aufgrund eines offensichtlichen Fehlers dieselbe Fehlermeldung angezeigt:
let alertController = UIAlertController(title: "Oops", message:"bla.", preferredStyle: UIAlertControllerStyle.Alert) alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil)) self.presentViewController(alertController, animated: true, completion: nil)
Aufgrund eines dummen Kopierfehlers von mir selbst hatte ich die Zeile self.presentViewController nicht eingefügt. Dies verursachte den gleichen Fehler.
quelle
In der Swift 2.2-Version hat das bei mir funktioniert
deinit { self.searchController?.view.removeFromSuperview() }
Ich finde es hilfreich!
quelle
Es ist kein Fehler. Es scheint, dass Sie vermeiden müssen, ViewController zu erstellen, ohne sie zu präsentieren. Also danach
SomeViewController()
oderlet variable: SomeViewController
du musst so etwas anrufenself.presentViewController(yourViewController ...etc)
. Wenn Sie dies nicht tun, erhalten Sie diese Warnung, wenn dieser View Controller freigegeben wird.quelle
Meins funktioniert so
func initSearchControl(){ searchController = UISearchController(searchResultsController: nil) if #available(iOS 9.0, *) { searchController.loadViewIfNeeded() } else { let _ = self.searchController.view } searchController.searchResultsUpdater = self searchController.dimsBackgroundDuringPresentation = false definesPresentationContext = true tableView.tableHeaderView = searchController.searchBar searchController.searchBar.sizeToFit() }
searchController.loadViewIfNeeded () löst das Problem, aber Sie müssen es nach der Initialisierung des searchController aufrufen
quelle
Wenn Sie einen Suchcontroller in
viewDidLoad()
erstellen und seine Suchleiste als Titelansicht des Navigationselements festlegen, wird kein starker Verweis auf den Suchcontroller erstellt, weshalb die Zuordnung aufgehoben wird.Also anstatt dies zu tun:
override func viewDidLoad() { super.viewDidLoad() // Create search controller let searchController = UISearchController(searchResultsController: nil) // Add search bar to navigation bar navigationItem.titleView = searchController.searchBar // Size search bar searchController.searchBar.sizeToFit() }
Du solltest das tun:
var searchController: UISearchController! override func viewDidLoad() { super.viewDidLoad() // Create search controller searchController = UISearchController(searchResultsController: nil) // Add search bar to navigation bar navigationItem.titleView = searchController.searchBar // Size search bar searchController.searchBar.sizeToFit() }
quelle
Ich habe Dereks Antwort verwendet, musste sie aber leicht ändern. Die bereitgestellte Antwort stürzte für mich ab, da der Aufruf von loadViewIfNeeded () erfolgte, bevor der resultSearchController definiert wurde. (Meine Erklärung war
var resultSearchController: UISearchController!
). Also habe ich es einfach danach verschoben und es hat funktioniert.
Wenn ich den Anruf ganz ausgelassen habe, ist der Fehler geblieben, daher bin ich mir sicher, dass er ein wesentlicher Bestandteil der Antwort ist. Ich konnte es unter iOS 8 nicht testen.
quelle
Es scheint, dass die Ansicht verzögert geladen ist. Wenn Sie den Controller zugewiesen haben und ihn nie anzeigen, wird die Ansicht nicht geladen. In diesem Fall erhalten Sie diese Warnung, wenn der Controller freigegeben wird. Sie können es einmal anzeigen oder die Methode loadViewIfNeed () aufrufen oder mit 'let _ = controller.view' das Laden der Ansicht erzwingen, um diese Warnung zu vermeiden.
quelle
Ich bin etwas spät zur Party, aber hier ist meine Lösung:
var resultSearchController: UISearchController! override func viewDidLoad() { super.viewDidLoad() self.resultSearchController = ({ let searchController = UISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.dimsBackgroundDuringPresentation = false searchController.searchBar.sizeToFit() return searchController })() self.tableView.tableHeaderView = self.resultSearchController.searchBar self.tableView.reloadData() }
Ich hoffe es funktioniert bei dir.
quelle