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

时间:2012-06-29 15:49:08

标签: objective-c ios uitableview

我是Objective-c的新手(以及Apple的所有事情)。

我正在设计一个iOS应用程序并遇到了一个对我来说非常有趣的错误。基本上,我从一个VC(LoginViewController)开始,沿着我将另一个VC推送到我的导航控制器(MyProfileViewController)的方式。

但是当我通过堆栈回到LoginViewController时,触摸屏幕上的任何对象都会导致EXEC_BAD_ACCESS错误。经过一番努力之后,我决定更改视图中的表名(我的ViewControllers都包含一个UITableView,在各自的.m文件中定义,并且我都命名为'myTable'。)

事实证明,对于我的应用程序,除了导致可读性差之外(你不必在这一点上指责我),命名两个表同样是导致崩溃的原因。所以我想当MyProfileViewController被释放时,它也会从LoginViewController发布'myTable'???

正常的错误,我意识到我的错误,尝试从中学习,继续前进。但是这对于我为什么首先造成崩溃是没有意义的。任何见解?作为参考,这是我在两个ViewControllers中定义和发布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];
}

1 个答案:

答案 0 :(得分:2)

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

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

如果这样做,那么一个类中的实例变量的名称是否恰好与另一个类中的名称相同并不重要。类实例变量的范围仅限于该类。 (顺便说一下,作为一种风格问题,很多人用类下划线来表示它们的类实例变量,通常是将它们与类属性和局部变量区分开来。)

第二(与你原来的问题无关),我建议在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];
}

(显然,请从release删除dealloc声明。)

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

如果您使用ARC,通常会为您清理这种愚蠢的内存管理问题,但如果您不使用ARC,则可能需要调整释放位置。