在不同的类中释放/访问同名的不同对象

我是一个新手objective-c(和苹果,所有事情)。

我正在devise一个iOS应用程序,遇到了一个我觉得很有趣的bug。 基本上,我开始在一个VC(LoginViewController),并沿着我的方式推另一个VC到我的导航控制器(MyProfileViewController)。

但是当我通过栈回到LoginViewController时,触摸屏幕上的任何对象都会导致EXEC_BAD_ACCESS错误。 在一些头部划伤之后,我决定改变视图中的表名(我的两个ViewController都包含一个UITableView ,它们在各自的.m文件中定义,而且两者都命名为'myTable')。

事实certificate,对于我的应用程序来说,除了导致可读性较差外(在这一点上您不必指责我),将两个表命名为导致崩溃的原因。 所以我想当MyProfileViewController被释放时,它从LoginViewController释放“myTable”以及?

正常的错误,我意识到我的错误,试图从中吸取教训,继续前进。 但是,这对我而言并没有什么意义,为什么它首先造成了崩溃。 任何见解? 作为参考,以下是我在两个ViewController中定义和释放UITableView的方法。

 @implementation MyProfileViewController//same format as LoginViewController UITableView* myTable;//It's since been renamed to something more descriptive //code... -(void)viewDidLoad{ [super viewDidLoad]; myTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStyleGrouped]; [myUpdateTable setDataSource:self]; [myTable setDelegate:self]; [self.view addSubview:myTable]; } //code... -(void)dealloc{ [myTable release]; [super dealloc]; } 

首先,我是否正确地读取了你的代码,你的UITableView没有在@interface定义? 如果是这样,你已经定义myTable是一个全局variables。 这不是一个好主意,虽然我很惊讶连接器没有抱怨,如果你在两个.m文件中使用了相同的全局variables(但它肯定会解释为什么使用相同的名称会导致问题)。 你真的希望你的UITableView是一个实例variables。 您可以在.m文件的顶部定义私有实例variables,如下所示(在@implementation之前):

 @interface MyProfileViewController () { UITableView* _myTable; } @end 

如果你这样做,那么在一个类中你的实例variables的名称是否与另一个类中的名称相同并不重要。 类实例variables的作用域限于该类。 (顺便说一句,就风格而言,许多人在其实例variables前加上下划线,通常将它们与类属性和局部variables区分开来。)

其次(和你原来的问题无关),我build议释放viewDidLoad ,因此:

 - (void)viewDidLoad { [super viewDidLoad]; _myTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStyleGrouped]; [_myTable setDataSource:self]; [_myTable setDelegate:self]; [self.view addSubview:_myTable]; [_myTable release]; } 

(显然,从你的dealloc删除release语句。)

没有理由推迟release :当你分配/ init,它有一个保留计数+1,当你addSubview它得到一个保留计数为+2,当你释放时,你只需返回到+1 (这意味着它不会被交易,因为self.view是保留它,但当视图最终释放它时,你的tableview将自动处理)。 但是,有很好的理由推迟它(如果在推送到新的视图控制器后遇到了didReceiveMemoryWarning ,您的原始代码将会泄漏)。

如果你使用ARC,这种愚蠢的内存pipe理问题通常会为你清理,但是由于你没有使用ARC,你可能需要调整你发布的地方。