Iphone应用程序在iOS 4.3中因EXC_BAD_ACCESS错误而崩溃,但在以前的版本中运行正常

时间:2011-03-14 14:29:48

标签: iphone ios uitableview

我创建了一个苹果批准的应用程序,目前可以在appstore中购买。但是在4.3更新之后,当使用EXC_BAD_ACCESS错误滚动UITableView时它会崩溃。 NSZombieEnabled = YES,将使应用程序再次运行,但当然这不是解决方案;)错误报告在以下行的Main类中:

int retVal = UIApplicationMain(argc, argv, nil, nil);

堆栈跟踪也无法帮助我:

> #0  0x00faf09f in objc_msgSend ()
> #1  0x04c7b9e0 in ?? ()
> #2  0x00d6004c in CFRelease ()
> #3  0x00e42369 in -[__NSArrayM removeObjectAtIndex:] ()
> #4  0x00e3dcfc in -[NSMutableArray removeObjectsInRange:] ()
> #5  0x003507a5 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] ()
> #6  0x0034890c in -[UITableView layoutSubviews] ()
> #7  0x01d80a5a in -[CALayer layoutSublayers] ()
> #8  0x01d82ddc in CALayerLayoutIfNeeded ()
> #9  0x01d280b4 in CA::Context::commit_transaction ()
> #10 0x01d29294 in CA::Transaction::commit ()
> #11 0x01d2946d in CA::Transaction::observer_callback ()
> #12 0x00e2a89b in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
> ()
> #13 0x00dbf6e7 in __CFRunLoopDoObservers ()
> #14 0x00d87857 in CFRunLoopRunSpecific ()
> #15 0x00d87761 in CFRunLoopRunInMode ()
> #16 0x017371c4 in GSEventRunModal ()
> #17 0x01737289 in GSEventRun ()
> #18 0x002dec93 in UIApplicationMain ()
> #19 0x000026d4 in main (argc=1, argv=0xbffff068) at
> /Users/geoffrey/Documents/iPhone
> projecten/Xcode Projecten/HU
> Rooster/main.m:14

有人可以帮我解决这个问题吗? 我现在试着让它工作2天:(

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = customCell;
        self.customCell = nil;
    }
    int num = indexPath.row;

    if (indexPath.section != 0) {
        for (int i=1; i <= indexPath.section; i++) {
            num = (num + [[sectorSize objectAtIndex:(i-1)] intValue]);
        }
    }
    // Configure the cell...
        cell.tijdLabel.text = [NSString stringWithFormat:@"%@ - %@", [tijdBeginList objectAtIndex:num], [tijdEindList objectAtIndex:num]];
        cell.lesVormLabel.text = [lesVormList objectAtIndex:num];
        cell.docentLabel.text = [docentList objectAtIndex:num];
        cell.lokaalLabel.text = [lokaalList objectAtIndex:num];
        cell.opmerkingLabel.text = [opmerkingList objectAtIndex:num];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

7 个答案:

答案 0 :(得分:6)

检查Custom Cell实现的dealloc方法,并确保[super dealloc]是最后一条指令。我有一个类似的问题,结果发现我在发布一些视图标签和其他项目之前调用了[super dealloc]。

答案 1 :(得分:0)

这些行

> #3  0x00e42369 in -[__NSArrayM removeObjectAtIndex:] ()
> #4  0x00e3dcfc in -[NSMutableArray removeObjectsInRange:] ()
> #5  0x003507a5 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] (

让我预感到问题出在你在cellForRowAtIndexPath选择器中创建的单元格中。有些东西最终可能会被释放。

答案 2 :(得分:0)

有些东西被过度释放,而且从堆栈跟踪的外观来看,似乎是UITableViewCell被释放的次数太多了。

你说NSZombieEnabled = YES让它保持运行,这实际上让我感到惊讶。 NSZombie的作用,至少在我使用它的时候,是它告诉你发送了什么消息的解除分配的对象,但应用程序仍然崩溃。

为了进一步帮助您,如果您能提供NSZombie的输出以及您的实施,将会有所帮助:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

编辑:我从未使用过界面构建​​器,但我发现了一条我发现可疑的行:

self.customCell = nil;

如果customCell属性是retain属性,该行将释放自定义单元格。尝试将该属性更改为assign属性。

差异可能是

[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

用于保留以前版本中的自定义单元格,但不在4.3中。你应该搞清楚,这样你就不会泄漏旧版本。如果您需要更多帮助,请发表评论。

编辑2:好的,我还有一个想法。

您可以检查单元格的保留计数:

NSLog(@"Retain count: %i", [cell retainCount]);

您可以检查不同位置的保留计数,并在4.3和之前的版本之间进行比较。也许这样你可以弄清楚发生了什么变化。

我还阅读了loadNibNamed:owner:options:的文档,发现了以下可能相关的内容:

  

(要建立插座连接,此方法使用setValue:forKey:方法,这可能会导致插座中的对象自动保留。)

文档说可以保留对象 ,所以我猜这种行为可能会在版本之间发生变化。

答案 3 :(得分:0)

您的错误是您将cell指针指定给customCell指针,然后将customCell设置为nil,这意味着cell将指向非有效的对象。

使用cell = [[customCell copy] autorelease];代替,你应该好好去。

答案 4 :(得分:0)

首先,您正在向后读取堆栈跟踪。崩溃发生在[__NSArrayM removeObjectAtIndex:](或刚好在下面)。

其次,问题表明对象已创建,放入数组,然后释放到释放点,而数组仍保留在其上。这是一个非常常见的过度释放问题。

下面:

    [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = customCell;
    self.customCell = nil;

您获取对customCell的引用,然后立即释放它。它可能存在的唯一原因是因为NIB加载可能会在加载时保留/自动释放对象。

Rog建议保留/自动释放细胞是一个很好的建议。

但是存在更大的问题; 您正在尝试绘制表格视图时加载一个笔尖

加载NIB是一种相对冰冷的操作,可以在绘制表格时对性能敏感。由于这个原因,您的应用程序的滚动和/或用户交互很可能会“笨拙”。

虽然cell = [[customCell retain] autorelease];可能会修复崩溃,但我建议您重构代码,以便在表格渲染过程中不做那么昂贵的事情。

答案 5 :(得分:0)

我遇到同样的问题......

in cellForRowAtIndexPath:(NSIndexPath *)indexPath

使用xib文件的CellIdentifier检查CellIdentifier ...

答案 6 :(得分:0)

让你的CellIdentifier = @“CustomCell”

这将解决您的问题