7

我正在开发一个标签栏应用程序,其中一个标签有一个连接到 UISearchBar 的 UISearchDisplayController。这一切都在NIB中连接起来并且正在工作。当我点击搜索栏时,Scope 和 Cancel 按钮会飞入等,并且搜索委托会正确更新结果表。

但是,我试图在viewDidLoad消息而不是 NIB 中实现相同的代码,但是当我从 NIB 中删除搜索显示控制器并取消注释我的代码以在函数中创建相同的控制器时,它不起作用。好像没有建立一些基本连接,所以我的所有搜索委托功能都没有被调用。

这是我工作的NIB 版本的搜索显示控制器。它连接到搜索栏、UINavigationController子类 ( MASearchController) 并且其根视图连接为searchContentsController.

替代文字 http://img192.imageshack.us/img192/3050/screenshot20100307at304.png

现在这就是您希望在代码中创建相同的内容,对吧?我正在做的是将 UISearchBar 留在 NIB 中,以便在代码中一次消除一个难题。

// [MASearchController viewDidLoad]
UISearchDisplayController *searchController = [[[UISearchDisplayController alloc]
    initWithSearchBar:searchBar
    contentsController:[[self viewControllers] objectAtIndex:0]] autorelease];
[searchController setDelegate:self];
[searchController setSearchResultsDelegate:self];
[searchController setSearchResultsDataSource:self];

我在运行时检查了所有对象,它们都签出。本质上,我已经从 NIB 中删除了搜索显示控制器,然后放入代码以在viewDidLoad消息中创建它。

为什么这行不通?搜索键盘出现但我的搜索和按钮动画功能都不起作用???

4

2 回答 2

9

哇,我才发现问题所在。

我想,因为 UIViewController 的 searchDisplayController 属性是在 initWithSearchBar:contentsController: 消息中设置的,所以我仍然会自动释放我的指针副本,但是当我删除autorelease这个愚蠢的东西时,它开始工作了。啊啊啊。为什么它不保留自己的副本(UIViewController)?

于 2010-03-07T06:14:02.567 回答
4

通常子对象不应保留其父对象。在这种情况下,它的父控制器应该保留子控制器(即搜索显示控制器)。

当您在 NIB 文件中创建 SDC 时,这已自动为您完成,因为它已添加到视图控制器的searchDisplayController属性中,因此在视图控制器的生命周期内保留。

但是,由于searchDisplayController在视图控制器上设置属性被认为是使用私有 api。您应该只添加一个 ivar 来保留它并在 dealloc 上手动释放它。

简单地删除autorelease调用是一个内存泄漏,因为你离开了一个你编辑过的对象init而不保存对它的引用,所以我认为这不是正确的答案。

相反,您应该将其searchController正确保留在 ivar 中并在 dealloc 上正确释放它,就像您希望在视图控制器的生命周期内保持活动状态的任何对象一样。

于 2012-02-09T11:21:08.880 回答