Programing

할당을 해제하는 동안 뷰 컨트롤러의 뷰를로드하려고합니다. UISearchController

lottogame 2020. 10. 9. 08:45
반응형

할당을 해제하는 동안 뷰 컨트롤러의 뷰를로드하려고합니다. UISearchController


UISearchController' in my UIVIew'sviewDidLoad` 를 만드는 코드가 있습니다.

 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

    })()

이 폐쇄가 완료된 직후 다음 경고가 콘솔에 나타납니다.

Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UISearchController: 0x154d39700>)

나는 내가 뭘 잘못하고 있는지 이해하지 못한다. 이 비슷한 질문 은 실제로 내 상황이 아닙니다 (적어도 나는 그렇게 생각하지 않습니다). 무슨 일이야?


UISearchController의 뷰는 할당을 해제하기 전에 수퍼 뷰에서 제거되어야합니다. (버그라고 추측)

목표 -C ...

-(void)dealloc { 
    [searchController.view removeFromSuperview]; // It works!
}

스위프트 3 ...

deinit {
    self.searchController.view.removeFromSuperview()
}

나는이 문제로 몇 주 동안 고생했다. ^^


해결되었습니다! 간단한 수정이었습니다. 이 코드를 변경했습니다

class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController = UISearchController()

이에:

 class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController: UISearchController!

이것은 문제를 해결합니다.


나를 위해 일한 Swift 버전은 다음과 같습니다 (JJHs 답변과 유사).

deinit{
    if let superView = resultSearchController.view.superview
    {
        superView.removeFromSuperview()
    }
}

class SampleClass: UITableViewController, UISearchBarDelegate {

private let searchController =  UISearchController(searchResultsController: nil)

 override func viewDidLoad() {
        super.viewDidLoad()

        searchController.loadViewIfNeeded() // Add this line before accessing searchController
 }

}

UISearchController를 완전히 설정 하기 전에 viewDidLoad에 줄을 추가하여 몇 가지 솔루션을 함께 해킹하여 작업을 수행했습니다 .

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()

}

Swift2에서는 명백한 버그로 인해 동일한 오류 메시지가 나타납니다.

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)

나 자신의 어리석은 복사 오류로 인해 self.presentViewController 행을 포함하지 않았습니다. 이로 인해 동일한 오류가 발생했습니다.


나를 위해 일한 Swift 2.2 버전에서

deinit {
    self.searchController?.view.removeFromSuperview()
}

도움이된다고 생각합니다!


내 것이 이렇게 작동합니다

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 () 는 문제를 해결하지만 searchController를 초기화 한 후 호출해야합니다.


에서 검색 컨트롤러를 viewDidLoad()만들고 탐색 항목의 제목보기로 검색 막대를 설정 하면 검색 컨트롤러에 대한 강력한 참조가 생성되지 않으므로 할당이 해제됩니다.

따라서 이렇게하는 대신 :

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()
}

다음을 수행해야합니다.

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()
}

I used Derek's answer, but had to change it slightly. The answer that was provided crashed for me because the call to loadViewIfNeeded() happened before the resultSearchController was defined. (My declaration was

var resultSearchController: UISearchController!

). So I just moved it afterwards and it worked.

If I left out the call entirely, the bug remained, so I'm sure it is an essential part of the answer. I was unable to test it on iOS 8.


It's not a bug. It seems that you have to avoid creating ViewControllers without presenting them. So after SomeViewController() or let variable: SomeViewController you have to call something like this self.presentViewController(yourViewController ...etc). If you don't do that, you will get this warning when this view controller will be dealocated.


It seem the view is lazy loaded, if you allocated the controller and never show it, the view is not loaded. In this case, if the controller is deallocated, you will received this warning. you could show it once, or call it's loadViewIfNeed() method, or use 'let _ = controller.view' to force load the view to avoid this warning.


I'm a bit late to the party, but here's my solution:

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()
}

I hope it works for you.

참고URL : https://stackoverflow.com/questions/32282401/attempting-to-load-the-view-of-a-view-controller-while-it-is-deallocating-uis

반응형