使用 UISearchBar 作为 UITableView 的 header 视图不可避免的保留周期?
Unavoidable retain cycle using UISearchBar as UITableView's header view?
我 运行 进入这个问题是因为我正在构建一个使用 UISearchController
和它的 UISearchBar
成员的基本 UI。我的 tableView 是一个弱 IBOutlet,就像 Apple Docs 演示的那样,我将它的 tableHeaderView 属性 设置为搜索栏成员。
//Snippet from viewDidLoad
UISearchController* searchController = [self createSearchController];
UISearchBar* searchBar = searchController.searchBar;
searchBar.userInteractionEnabled = NO;
self.tableView.tableHeaderView = searchBar; //The assignment in question
[NetworkStuff makeCall:^(Response *response) {
//handle success
searchBar.userInteractionEnabled = YES; //local variables
searchController.active = YES;
...
} failure:^(Response *response) {
//handle failure
...
}];
当我从堆栈中弹出视图时,它的 dealloc 方法永远不会被调用,即使我在 viewWillDisappear:
中将 tableHeaderView 设置为 nil 也是如此。我需要注释掉的唯一一行才能看到调用的 dealloc 是初始分配。
有人知道为什么会发生这种情况吗?
编辑:
发现了一些有趣的行为。同样根据 Apple Docs,我将控制器的 definesPresentationContext
变量设置为 YES
。在将 tableViewHeader 赋值保留在固定的保留周期中时注释掉这一点,即使我没有消除 tableViewHeader。但是,在viewDidLoad
中设置definesPresentationContext
并在viewWillDisappear
中清除它re-introduces保留周期。
偶然发现这个答案:
UISearchController retain issue
该解决方案似乎在 viewDidDisappear:
中明确取消了 UISearchController(请注意,我无法在 viewWillDisappear:
中使用它)。由于该代码在 swift 中,我将在此处将其转录为 Objective-C:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if (!self.presentingViewController) {
[self.searchController dismissViewControllerAnimated:NO completion:nil];
}
}
正如原始答案所指出的,检查 self.presentingViewController
不存在在另一个视图控制器被推到视图顶部的情况下很有帮助,因为我们会回到这一页。很可能,我们只想在弹出包含它的视图控制器时关闭 searchController。
我 运行 进入这个问题是因为我正在构建一个使用 UISearchController
和它的 UISearchBar
成员的基本 UI。我的 tableView 是一个弱 IBOutlet,就像 Apple Docs 演示的那样,我将它的 tableHeaderView 属性 设置为搜索栏成员。
//Snippet from viewDidLoad
UISearchController* searchController = [self createSearchController];
UISearchBar* searchBar = searchController.searchBar;
searchBar.userInteractionEnabled = NO;
self.tableView.tableHeaderView = searchBar; //The assignment in question
[NetworkStuff makeCall:^(Response *response) {
//handle success
searchBar.userInteractionEnabled = YES; //local variables
searchController.active = YES;
...
} failure:^(Response *response) {
//handle failure
...
}];
当我从堆栈中弹出视图时,它的 dealloc 方法永远不会被调用,即使我在 viewWillDisappear:
中将 tableHeaderView 设置为 nil 也是如此。我需要注释掉的唯一一行才能看到调用的 dealloc 是初始分配。
有人知道为什么会发生这种情况吗?
编辑:
发现了一些有趣的行为。同样根据 Apple Docs,我将控制器的 definesPresentationContext
变量设置为 YES
。在将 tableViewHeader 赋值保留在固定的保留周期中时注释掉这一点,即使我没有消除 tableViewHeader。但是,在viewDidLoad
中设置definesPresentationContext
并在viewWillDisappear
中清除它re-introduces保留周期。
偶然发现这个答案: UISearchController retain issue
该解决方案似乎在 viewDidDisappear:
中明确取消了 UISearchController(请注意,我无法在 viewWillDisappear:
中使用它)。由于该代码在 swift 中,我将在此处将其转录为 Objective-C:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if (!self.presentingViewController) {
[self.searchController dismissViewControllerAnimated:NO completion:nil];
}
}
正如原始答案所指出的,检查 self.presentingViewController
不存在在另一个视图控制器被推到视图顶部的情况下很有帮助,因为我们会回到这一页。很可能,我们只想在弹出包含它的视图控制器时关闭 searchController。