滚动时UITableView崩溃

时间:2011-05-12 02:37:02

标签: iphone objective-c ios uitableview

我一直在尝试为我的朋友创建一个乐队的应用程序,我一直在尝试使用自定义TableViewCell来显示网站上的新闻文章。我的主要目标是从网站获取所有数据,将其存储在NSMutableArray中,然后在我的自定义单元格中显示。

应用程序在加载前5-6个单元格时运行正常。但是,当我开始滚动时,应用程序崩溃了。我已经在cellForRowAtIndexPath:方法中找到了它。使用GDB,我也发现在创建NSMutableArray数据后,一旦程序运行,滚动后,我的数组似乎是自动释放的。我不确定为什么会这样。到目前为止,这是我的代码所用的内容:

在HomeViewController.h中:

@interface HomeViewController : UIViewController {
    NSArray *results;
    NSMutableArray *titles;
    NSMutableArray *dates;
    NSMutableArray *entries;
}

@property (nonatomic, retain) NSMutableArray *titles;
@property (nonatomic, retain) NSMutableArray *dates;
@property (nonatomic, retain) NSMutableArray *entries;

@end

在HomeViewController.m中:

- (void)viewDidLoad {
[super viewDidLoad];
titles = [[NSMutableArray alloc] init];
dates = [[NSMutableArray alloc] init];
entries = [[NSMutableArray alloc] init];

while((i+1) != endIndex){   
    NSString *curr_title = [[NSString alloc] init]; 
    NSString *curr_date = [[NSString alloc] init];
    NSString *curr_entry = [[NSString alloc] init];

    //do some character iterations across a string

    [titles addObject:curr_title];
    [dates addObject:curr_date];
    [entries addObject:curr_entry];

    [curr_title release];
    [curr_date release];
    [curr_entry release];
}
}

//此处有更多代码,已删除

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

static NSString *CellIdentifier = @"NewsCell";


NewsCell *cell = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle]
                                loadNibNamed:@"NewsCell"
                                owner:self options:nil];
//  cell = [topLevelObjects objectAtIndex:0];
    for(id currentObject in topLevelObjects){
        if([currentObject isKindOfClass:[UITableViewCell class]]){
            cell = (NewsCell *)currentObject;
            break;
        }
    }

}
NSLog(@"%d", indexPath.row);
NSLog(@"%d", titles.count);
cell.cellTitle.text = [titles objectAtIndex:indexPath.row];
cell.datePosted.text = [dates objectAtIndex:indexPath.row];
cell.preview.text = [entries objectAtIndex:indexPath.row];

return cell;
}

同样,前5-6个细胞出现了。滚动后,我尝试po titles并收到此错误:

Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000009 0x011b309b in objc_msgSend ()

我已经尝试在initWithNibName:中分配数组,但这似乎并不多。我已尝试移动viewDidLoad:中的所有代码,然后调用[super viewDidLoad],它也产生了相同的结果。对不起,这太长了,但我想人们需要查看我的代码。

3 个答案:

答案 0 :(得分:2)

我发现您发布的代码没有明显错误。试试enabling the NSZombieEnabled environment variable。这可以防止对象被释放,这样当您的应用程序“崩溃”时,您可以确定哪个对象导致了问题。

此外,您应该将所需对象分配给类的loadNibNamed:owner:options属性,而不是循环遍历IBOutlet返回的对象数组。有关示例,请参阅Loading Custom Table-View Cells From Nib Files


以下内容摘自您发布的新代码:

NSString *curr_title = [[NSString alloc] init];

//do some character iterations across a string

[titles addObject:curr_title];

[curr_title release];

NSString不可变(与NSMutableString一样)。您是否故意将空字符串添加到titles数组中?


回复您的评论:stringByAppendingString创建一个新的自动释放的NSString对象。

NSString *curr_title = [[NSString alloc] init];

// this leaks the original NSString object (curr_title no longer points to it);
// curr_title now points to a new, autoreleased NSString
curr_title = [curr_title stringByAppendingString:@"..."];

[titles addObject:curr_title];

// releasing the autoreleased NSString will cause your application to crash!
[curr_title release];

答案 1 :(得分:0)

问题可能出在NewsCell的实施上,你的所有属性都被保留了吗?

另外,HomeViewController是UIViewController的子类而不是UITableViewController的任何原因?

这应该可以正常工作:

NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewsCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];

答案 2 :(得分:0)

* EXC_BAD_ACCESS *是一个确定的迹象,表明您的某个对象已被释放(或未正确保留)。 NSZombieEnabled 在这里是你的朋友,正如titdecoy所暗示的那样 - 弄清楚什么对象被释放是一半的战斗。请务必在发布应用程序之前将其关闭,因为(正如钛金属指出的那样)它会阻止对象被释放。

我通常使用NSZombieEnabled和放置良好的断点的组合(所以我可以遍历代码直到它崩溃)来找出问题在代码中出现的位置。然后通常只需回溯即可找出对象被释放的位置。