【问题标题】:iOS Memory Warning tableView EXC_BAD_ACCESS crash in multi-view appiOS内存警告tableView EXC_BAD_ACCESS在多视图应用程序中崩溃
【发布时间】:2012-02-23 02:38:18
【问题描述】:

我正在努力弄清楚如何正确设置我的视图控制器以优雅地处理内存警告。

目前,每当应用收到内存警告时,我都会从导航控制器堆栈中更靠后的视图中收到 EXC_BAD_ACCESS 崩溃。

我的表格视图发生了错误的访问。这是我实例化它的方式:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    UITableView *table = [[[UITableView alloc] initWithFrame:CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.bounds.size.width, self.view.bounds.size.height - self.navigationController.navigationBar.bounds.size.height) style:UITableViewStyleGrouped] autorelease];
    table.dataSource = self;
    table.delegate = self;

    self.tableView = table;
    [self.view addSubview:table];
    [table release];

    ...other stuff...
}

这是我的 viewDidUnload:

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.tableView = nil;
}

出现内存警告时,按预期调用 viewDidUnload,但我在 self.tableView = nil 行上遇到 EXC_BAD_ACCESS 崩溃。

我是否在错误的位置设置了我的 tableView?我没有使用 nib 文件,所以我应该在其他地方构建它吗?我是否以某种方式错误地将其传递给视图控制器?等等等等

任何帮助将不胜感激。我还没有理解内存警告时发生的事件顺序,而 1 级内存警告似乎非常常见。

【问题讨论】:

    标签: iphone ios memory-management exc-bad-access


    【解决方案1】:

    您在table 上拨打了两次release;一次是在您创建它时使用autorelease 进行延迟 发布,在您将其添加为self.view 的子视图后再次使用[table release];。请记住,如果tableView 的属性是'retain',那么它将在分配时保留(当使用点语法分配时)——并且,当您添加它时,addSubview 也将保留table。因此,您只需将 autorelease 留在其中 - 因为该延迟发布(这将通过您说 self.tableView = table; 时发生的保留来平衡。

    【讨论】:

    • 是的,我一发布问题就看到了autorelease,哈哈。 摸额头 -- 谢谢你,先生。
    • 另外,我建议只使用 UITableViewController——它会为你完成 UITableView 的大量分配等操作。
    • 是的,我以前使用UITableViewController 是为了方便。不幸的是,我们现在需要在我们的一些屏幕上进行足够的视图自定义,我需要自己实例化表格视图的更细粒度的控制。再次感谢!
    • 问题:将autorelease 留在那里而不是[table release] 是否有优势,或者任何一种方法在这里都同样合适? (只是不是两者)
    • 如果删除autorelease 并保留retain,系统会清理table 的分配,而无需等待自动释放池块完成。如果您不再使用table 并且...other stuff... 将进行大量内存分配,这是最好的。
    【解决方案2】:

    试试这个:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.
        UITableView *table = [[[UITableView alloc] initWithFrame:CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.bounds.size.width, self.view.bounds.size.height - self.navigationController.navigationBar.bounds.size.height) style:UITableViewStyleGrouped] autorelease];
        table.dataSource = self;
        table.delegate = self;
    
        self.tableView = table;
        [self.view addSubview:table];
        //[table release]; You have already release table with autorelease.
    
        ...other stuff...
    }
    

    【讨论】:

    • 谢谢@fannheyward。你是对的。我将在这里接受我接受的答案的响应速度。
    猜你喜欢
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    相关资源
    最近更新 更多