Tof*_*zer 11 objective-c uiviewcontroller iphone-sdk-3.0
我有两个视图控制器A和B.从A,我导航到视图控制器B,如下所示:
// in View Controller A
// navigateToB method
-(void) navigateToB {
BViewController *bViewController =
[[BViewController alloc] initWithNibName: @"BView" bundle:nil];
bViewController.bProperty1 = SOME_STRING_CONSTANT;
bViewController.title = @"A TITLE OF A VC's CHOOSING";
[self.navigationController pushViewController: bViewController animated:YES];
[bViewController release]; //<----- releasing 0x406c1e0
}
Run Code Online (Sandbox Code Playgroud)
在BViewController中,属性bPropery1定义为如下复制(注意,B还包含UITableView和其他属性):
@property (nonatomic, copy) NSString *bProperty1;
Run Code Online (Sandbox Code Playgroud)
在A和B之间来回导航时,一切似乎都能正常工作.直到我在BViewController中包含的表视图中添加了一个UISearchDisplayController.现在,当我离开B,回到A时,应用程序崩溃了.
堆栈跟踪显示在崩溃时自动释放的搜索显示控制器的外观:
#0 0x009663a7 in ___forwarding___
#1 0x009426c2 in __forwarding_prep_0___
#2 0x018c8539 in -[UISearchDisplayController _destroyManagedTableView]
#3 0x018c8ea4 in -[UISearchDisplayController dealloc]
#4 0x00285ce5 in NSPopAutoreleasePool
Run Code Online (Sandbox Code Playgroud)
NSZombies显示:
-[BViewController respondsToSelector:]: message sent to deallocated instance 0x406c1e0
Run Code Online (Sandbox Code Playgroud)
而malloc的历史就指向已经在A的navigateToB方法中发布的bViewController:
Call [2] [arg=132]: thread_a065e720 |start ... <snip>
..._sendActionsForEvents:withEvent:] | -[UIControl sendAction:to:forEvent:] | -
[UIApplication sendAction:to:from:forEvent:] | -[**AViewController navigateToB**] |
+[NSObject alloc] | +[NSObject allocWithZone:] | _internal_class_createInstance |
_internal_class_createInstanceFromZone | calloc | malloc_zone_calloc
Run Code Online (Sandbox Code Playgroud)
有人可以给我任何关于这里发生的事情的想法吗?在navigateToB方法中,一旦bViewController被释放(在pushViewController之后),那应该是bViewController的.没有其他人知道它,因为它是navigateToB方法块的本地并且它已经被释放.
当从B导航回A时,在viewDidLoad,viewWillAppear等中将调用任何将重新进入navigateToB的内容.
它看起来像是某种方式搜索显示控制器在我的AViewController中有一些引用,因此它是自动释放的,它正在使用它的"东西",但我无法理解这是如何可能的,特别是当我使用副本传递数据时A和B之间
我会为此而烦恼.我确定这是我的错误所以我转向你,Stack Overflow传说任何关于如何解决这个问题的智慧或建议.
非常感谢.
小智 32
我通过将这些行添加到我的UITableViewController的dealloc方法来解决类似的问题,该方法是UISearchDisplayController的委托:
self.searchDisplayController.delegate = nil;
self.searchDisplayController.searchResultsDelegate = nil;
self.searchDisplayController.searchResultsDataSource = nil;
Run Code Online (Sandbox Code Playgroud)
我有点担心修复此问题的建议搜索显示控制器应该在dealloc中发布 - 您需要做的是删除搜索显示控制器对表视图控制器的指针,因为您的表视图控制器现在当你的搜索显示控制器稍后发布时,不应该离开.它就像你想要在dealloc中取消的任何其他委托引用一样.
将视图控制器推入导航控制器时,导航控制器将保留视图控制器.当弹出该视图控制器时,导航控制器会释放它.
UISearchDisplayController似乎是想看看您的视图控制器响应一个选择,并且因为它是从_destroyManagedTableView打电话,我猜的选择是searchDisplayController:willUnloadSearchResultsTableView:(您的视图控制器是搜索显示控制器的委托,对吗?).
@robert - 这个例子一定是错的,因为pushViewController确实保留了它的参数.页面上的所有其他示例要么在init之后立即自动释放,要么在推送后释放.