由于推送和弹出UIViewControllers,UINavigationController崩溃

时间:2010-05-11 00:16:48

标签: crash uinavigationcontroller exc-bad-access private-members pushviewcontroller

我的问题与我发现UINavigationController崩溃的原因有关。所以我先告诉你这个发现。请跟我一起去。

问题: 我有一个UINavigationController作为UIWindow的子视图,一个rootViewController类和一个自定义的MyViewController类。以下步骤将获得Exc_Bad_Access,100%可重现。:

[myNaviationController pushViewController:myViewController_1stInstance animated:YES];
[myNaviationController pushViewController:myViewController_2ndInstance animated:YES];

点击左后方tapBarItem两次(弹出两个myViewController实例)以显示rootViewController。

经过痛苦的半天尝试和错误后,我终于找到了答案,但也提出了一个问题。

解决方案:我在.m文件中声明了很多对象,这是一种声明私有变量以避免混淆.h文件的懒惰方式。例如,

#impoart "MyViewController.h"
NSMutableString*variable1;

@implement ...

-(id)init
{
   ...
   varialbe1=[[NSMutableString alloc] init];
   ...
}

-(void)dealloc
{
   [variable1 release];
}

由于某些原因,在加载myViewController_2ndInstance的视图后,当myViewController_1stInstance的视图被卸载(但仍然在导航控制器的堆栈中)时,iphone OS可能会松开这些“惰性私有”变量内存分配的跟踪。第一次点击后面的tapBarItem是好的,因为myViewController_2ndInstance'view仍然被加载。但是第二次点击后面的tapBarItem给了我地狱,因为它试图释放第一个实例。它调用[变量释放]导致Exc_Bad_Access,因为它随机指向(松散指针)。

要解决此问题很简单,请在.h文件中将variable1声明为@private。

以下是我的问题: 我一直在使用“懒惰的私有”变量很长一段时间没有任何问题,直到他们参与UINavigationController。这是iPhone OS中的错误吗?或者我对Objective C有一个根本的误解?请帮忙。

2 个答案:

答案 0 :(得分:3)

它可能与使用相同静态分配变量的视图控制器的两个实例相关。

换句话说,myViewController_1stInstancemyViewController_2ndInstance在内存中使用相同的variable1位置并相互覆盖。

@interface定义之后在花括号内部声明的变量具有由运行时为每个类实例分配的内存位置(每次调用[<ClassName> alloc]时。在全局范围内声明的变量(也就是说,在任何函数或类声明之外)只是:global。这意味着变量只能为应用程序的每个运行副本保存一个值。

Objective-C中没有真正的私有变量,但您可以在编译时将其隐藏在其他实例中,如here所述。

答案 1 :(得分:1)

有点迟到的反应,但我以前见过这个问题。不要同时推动两个viewControllers动画。在没有动画的情况下推送第一个,然后用动画推动第二个动画。 UINavigationController无法同时处理两个动画。