Ios 试图在视图控制器解除分配时加载视图控制器的视图。。。UISearchController

Ios 试图在视图控制器解除分配时加载视图控制器的视图。。。UISearchController,ios,swift,uisearchcontroller,Ios,Swift,Uisearchcontroller,我有一段代码可以在我的UIVIew的viewDidLoad`中创建一个UISearchController' self.resultSearchController = ({ let controller = UISearchController(searchResultsController: nil) controller.searchResultsUpdater = self controller.searchBar.delegate =

我有一段代码可以在我的UIVIew的viewDidLoad`中创建一个
UISearchController'

 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>)
不允许在视图控制器解除分配时尝试加载视图控制器的视图,这可能会导致未定义的行为()

我不明白我做错了什么。这不是我真正的处境(至少我不这么认为)。发生了什么事?

解决了!这是一个简单的修复。我更改了这个密码

class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController = UISearchController()
为此:

 class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

    var resultSearchController: UISearchController!

这解决了问题。

UISearchController的视图必须在解除分配之前从其superview中删除。(我猜这是一只虫子)

目的-C

-(void)dealloc { 
    [searchController.view removeFromSuperview]; // It works!
}
斯威夫特3

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

我为这个问题挣扎了几个星期^^

以下是对我有效的Swift版本(类似于JJHS的答案):


在完全设置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行。这导致了同样的错误。

我使用了德里克的答案,但不得不稍微修改一下。 为我提供的答案崩溃了,因为对loadViewIfNeeded()的调用发生在resultSearchController定义之前。(我的声明是

var resultSearchController: UISearchController!
)。后来我就把它搬走了,它成功了


如果我完全忽略了呼叫,错误仍然存在,因此我确信这是答案的一个重要部分。我无法在iOS 8上测试它。

这不是一个bug。似乎您必须避免在不显示视图控制器的情况下创建它们。因此在
SomeViewController()
let variable:SomeViewController
之后,您必须调用如下内容
self.presentViewController(您的viewcontroller…等)
。如果不这样做,则在解除分配此视图控制器时将收到此警告。

我参加聚会有点晚,但我的解决方案是:

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

我希望它对您有用。

在Swift 2.2版本中,它对我有用

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

我认为这很有帮助

viewdiload()
中创建搜索控制器并将其搜索栏设置为导航项的标题视图不会创建对搜索控制器的强引用,这就是它被解除分配的原因

class SampleClass: UITableViewController, UISearchBarDelegate {

private let searchController =  UISearchController(searchResultsController: nil)

 override func viewDidLoad() {
        super.viewDidLoad()

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

}
因此,与其这样做,不如:

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

我的是这样工作的

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.LoadViewIfRequired()解决了这个问题,但是您需要在初始化searchController之后调用它

视图似乎是延迟加载的,如果您分配了控制器并且从未显示它,则视图不会加载。在这种情况下,如果控制器被解除分配,您将收到此警告。您可以显示它一次,或者调用它的loadViewIfNeed()方法,或者使用“let=controller.view”强制加载视图以避免此警告。

如果我将其放入我的表VC
viewDidLoad()
,则工作正常。建议a)包括整个VC源代码清单,b)确保错误确实发生在你认为发生的地方和时间。另外,做更多的研究,例如:哪一个有相同的错误那么,我做了一个swift项目,做了所有的事情都是渐进式的,没有故事板,我没有问题,这是故事板的问题吗,我不知道,但我想你在用故事板,对吧?当我以编程的方式说的时候,我的意思是没有笔尖,没有故事板,所有的代码都可以工作fine@BaseZen我在
}()
之前和
}()
之后设置了断点。在闭包结束后抛出错误。我有一个
UIViewController
,而不是
tableViewController
@Larcerax我有一个故事板。它只包含一个导航控制器和一个UIViewController(它们已连接)。我将其更改为您的意思。:-)无论如何,这就是为什么在问题中包含整个源代码更好,但自己找到它是最好的;-)我也收到了这个恼人的警告,根据你的回答,我修复了一切。但我不知道为什么会这样!需要,而不是分配新的UISearchController…您能给我检查一下吗?不确定,我也想得到一个解释。如果我从var resultSearchController=UISearchController()更改为var resultSearchController:UISearchController!我遇到致命错误:在noOfRowInSection中展开可选值时意外发现nil。我有大量的数组,这是创建错误吗?建议我。我发现,我没有从故事板中执行委托和数据源,而是在代码中编写,问题就解决了。这真的很奇怪。。。但这对我也有好处。我想这确实是一个bug。我在
-viewDidLoad
中分配的
uisearchcontroller也有同样的问题。这肯定是一个bug-如果
UISearchController
在加载其视图之前解除分配,则会出现此警告。如果我点击搜索字段(从而加载视图),它不会出现。因此,在我的
dealoc
中,我调用
[self.searchController loadViewIfNeeded]
(iOS 9中新增),@Leehro的评论是我的答案。结果是
如果#可用(iOS 9.0,*){self.searchController?.loadViewIfNeeded()}
我会在@Leehro的评论中补充说,在dealloc中不需要这样做,你可以在viewDidLoad中执行loadViewIfNeeded。多亏了@Leehro和@Clafou。。。添加调用
[self.searchController loadViewIfNeeded](Obj-C)是解决我代码中问题的答案。我还尝试了这里给出的所有其他解决方案,但没有一个解决方案抑制了警告(尽管搜索控制器在运行时起作用);这就成功了。非常感谢。这对我也有帮助,但我必须在初始化UISearchController后添加这一行<代码>self.searchController=({let controller=UISearchController(se
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()
    }