内存警告后,自定义UITableView headerView消失

时间:2010-12-31 02:09:13

标签: iphone cocoa-touch ios uitableview

我有UITableViewController。我在tableView方法中为loadView创建了一个自定义headerView,如下所示:

(void)loadView {
    [super loadView];

    UIView* containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height * 2 )];  
    containerView.tag = 'cont';
    containerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;

    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(padding, height, width, height);
    ... //configure UIButton and events

    UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"] highlightedImage:[UIImage imageNamed:@"highlight.png"]];    
    imageView.frame = CGRectMake(0, 0, width, height );
    ... //configure UIImageView

    [containerView addSubview:button];
    [containerView addSubview:imageView];
    self.tableView.tableHeaderView = containerView;

    [imageView release];
    [containerView release];
}

其他任何方法(viewDidLoad / Unload等)都没有重载。

此控制器托管在一个标签中。当我切换到另一个选项卡并模拟内存警告,然后返回到此选项卡时,我的UITableView缺少我的custon标头。正如我所料,所有行/部分都是可见的。将BP放在上面的loadView代码中,我看到在内存警告后切换回选项卡时调用它,但我实际上看不到标题。

关于我在这里缺少什么的想法?

编辑:这发生在设备和模拟器上。在设备上,我只是通过在我的后台打开一堆不同的应用程序时发出内存警告。

9 个答案:

答案 0 :(得分:6)

loadView方法不应该调用super。尝试删除[super loadView];这可能很好地解决了你的问题。其他重写的视图方法(viewDidLoad,viewWillAppear等)可以调用super就好了。请参阅以下文档:

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

确认。

答案 1 :(得分:2)

保持containsView而不是释放它。并在tableView中返回它:viewForHeaderInSection:(UITableViewDelegate方法)。

答案 2 :(得分:2)

我遇到了类似的问题,虽然它似乎没有根据他的代码解释OP的情况;我只想把它放在这里以防万一其他人遇到这个。

我将标题视图保留在实例变量中。在我的viewDidLoad中,我检查这个变量是否为nil,如果是,那么我创建视图,保留并设置实例变量并将tableHeaderView设置为它。问题是这个条件只有一次,因为我的实例变量在我第一次创建之后永远不会是nil;但是,当存在内存警告时,表视图的tableHeaderView属性设置为nil,因此不再有标题视图,即使我仍然有一个视图实例变量。

解决方案要么更改检查以查看表视图的tableHeaderView的属性是否为nil(然后每次设置为nil时重新创建标题视图),或者(因为在此case我仍然将视图保留在实例变量中)将赋值移到if-block之外的tableHeaderView,因此每次运行viewDidLoad时,我们都会确保重新分配标题如果设置为nil,则查看tableHeaderView

答案 3 :(得分:0)

宽度和高度是多少?在记忆警告后它们是否可能为零?

答案 4 :(得分:0)

这是正常的方式,iOS使用这种方式来减少内存,同时接收内存问题,然后它会释放一些UI元素,那也会调用方法'didUnLoad'...你必须释放方法中的headerView' didUnLoad',设置为nil,然后在方法'didLoad'中创建headerView,如果它是nil,然后将它添加到tableView ....  iOS将自动释放一些UI元素,同时面对内存警告。

答案 5 :(得分:0)

我遇到了一个类似的问题,导致我的自定义标头在收到内存警告后没有重新加载uitableview。我目前创建标题的实现是

- (void)viewDidLoad 
{
    [super viewDidLoad];

    if (_tableHeaderView == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"DetailHeaderView" owner:self options:nil];
        self.tableView.tableHeaderView = _tableHeaderView;
    }
}

并解决问题我只是将此行添加到我的didReceiveMemoryWarning

_tableHeaderView = nil

现在在发送内存警告后重新加载 很抱歉,如果这已经得到了回答,但我没有看到我的问题的明确答案,并认为我会在这里为其他人播放这个。

快乐编码

答案 6 :(得分:-1)

这个问题是众所周知的。例如,如果您使用TableViewDelegate tableView:viewForHeaderInSection:,它也将无效。

问题是iOS而不是你。关于tableHeaderView的问题并不多,因为没有人使用它,因此Apple没有得到任何BugTracker条目......

查看较早的问题:herehere是其他问题。

所以我认为这确实是一个SDK错误......

答案 7 :(得分:-1)

在表视图上执行reloadData可能会有所帮助

答案 8 :(得分:-2)

通过查看loadView,我可以看到的唯一问题是您尝试使用字符串标记containerView。据我所知,这应该是NSInteger