如何确保popToRootViewControllerAnimated有效?

时间:2012-03-22 23:19:57

标签: objective-c ios5 uiviewcontroller uinavigationcontroller segue

我有一个UINavigationController,当用户循环浏览页面时(总是相同的顺序),它会将三个视图推送到它上面 - 我将它们称为views0,1和2,以与导航控制器指示对齐。视图在Storyboard中创建。

当完成视图的进展,并且用户想要返回到开头时,我使用popToRootViewControllerAnimated:YES来响应按钮按下,并且UI适当地返回到view0。但是,如果我再次进行循环,我偶尔会得到“幻影”日志语句以响应应用程序范围的通知,清楚地表明view1(中间视图)从未完全解除分配。我只在xcode 4.2.1中使用ARC而只使用iOS5 +代码,所以ARC应该很好地处理好事情。

我已经看到一些帖子暗示ARC不会释放引用计数未降至0的视图,所以我已经尽力将属性设置为nil完成后,并进行了双重检查当我推到最终视图时什么也没有留下......而且NavigationController之外的任何内容都没有引用view1(我知道)。为僵尸和内存泄漏分析应用程序不会产生任何结果。

如何查看/记录/调试可能仍在引用视图的内容?我怎么能说它没有放入能防止dealloc的内容而被成功解除了?

我的代码(基本上)如下:

view0在故事板中使用“推送”segue推送到view1。

查看1:

- (void)viewDidLoad
    { 
    [super viewDidLoad];

    /* register as observer for some notifications */
    /* set properties and format an image or two */
    }

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

/* start some animation here */
}


- (void) receiveNotification {

NSObject *newObject = [[NSObject alloc] init];

[newObject doStuff];

/* Remove notification observers */

}


- (void)objectDelegateMethod:(NSDictionary *) dataReturned {

/* do stuff with dataReturned */
self.propertyName = dataReturned;

[self performSegueWithIdentifier:@"AllDone" sender:self];

}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

if ([[segue identifier] isEqualToString:@"AllDone"])
{

View2ViewController *destinationView = [segue destinationViewController];

destinationView.propertyMagic = self.propertyName;

[self setPropertyName:nil];
//do same with all other properties

}

视图2:

- (void)viewDidLoad
{

/* display things based on self.propertyMagic */

}


- (IBAction)userStartsOverButton:(id)sender {

[self.navigationController popToRootViewControllerAnimated:YES];

}

鉴于上述(粗略)结构,如果我不删除view1作为通知的观察者,它会继续响应并输出到日志,即使我看不出为什么它没有被解除分类。即使我删除观察者,内存使用量也会继续增加,因为我在应用程序运行中循环并最终崩溃(仪器中没有检测到泄漏)。

我如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

如果你有泄漏和僵尸,那么......你可能没有任何泄漏或过度释放。

要在ARC下“看到”dealloc,您可以在班级中添加空记录dealloc

- (void)dealloc
{
    NSLog(@"%s:%d", __func__, __LINE__);
}

答案 1 :(得分:0)

您可以检查的一件事是,是否有任何其他Object具有指向view1的(strong)指针。如果是这样,您可能希望将其更改为(weak)或仅保留对它的引用。 (查看view0和view1之间以及view1和view2之间可能的保留周期,也许它们彼此保持引用。)

ARC将在对象上释放,如果它不再由任何其他对象拥有。所以你也可以尝试覆盖view0上的-popToRootViewControllerAnimated:方法并调用类似的东西:

self.view1 = nil;

如果view0是唯一保持对view1的引用的对象,则应释放view1(dealloced)。