2012-07-09 111 views
0

我正在做一个iOS列出文档字典中的文件。我想在UITableView中显示这些数据,问题在于它无法正常工作。 它将数据加载到视图中。 然后应用冻结并调用EXC_BAD_ACCESS
这是我的代码:UITableView显示数据,然后崩溃

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    timesRun = 0; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectoryPath = [paths objectAtIndex:0]; 
    NSString *bundleRoot = [[NSBundle mainBundle] bundlePath]; 
    dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:nil]; 
    [bundleRoot release]; 
    NSLog(@"Count: %i",[dirContents count]); 
    return [dirContents count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableViewData cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    UITableViewCell *cell = nil; 
    int Locatation = indexPath.row; 
    Locatation++; 
    cell = [tableViewData dequeueReusableCellWithIdentifier:@"MyCells"]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyCell"]autorelease]; 
    } 
    //cell.textLabel.text = [NSString stringWithFormat:@"Cell: %i",Locatation]; 
    cell.textLabel.text = [dirContents objectAtIndex:timesRun]; 
    timesRun++; 
    return cell; 
    NSLog(@"Did return"); 
} 
- (void)tableView:(UITableView *)tableViewDat didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    NSLog(@"%@",cell.textLabel.text); 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

回答

0

我的问题有点像马里奥的回答。 [dirContents count]返回一个高于的值,而不是它可以从数组中添加对象的次数。

换句话说,这是一个超出界限的错误。

+0

是的。但我认为越界是来自你的timesRun ++,它每次调用cellForRowAtIndexpath时都会增加(这是每次表需要检查当前显示的单元格时,最有可能比你的数组大小更多)。你真的不需要自己保留一个柜台(并且它也不像你所做的那样工作)。如果你有更多的跟进qstns,请随时在这里问。 – Mario 2012-07-09 18:43:48

1

这将显示表视图数据源的概念的基本误解。

我的建议:

创建一个包含任何实现代码如下方法之外文件的数组。然后你使用该数组来提供tableview。

使用array.count返回numberofrowsatindexpath。 另外,在cellforrowatindexpath上提供细胞时,请勿使用迭代/计数器。 tableview使用indexpath参数询问数组的每个元素。你访问它是这样的:

ID对象= [数组objectArIndex:indexPath.row]

然后使用对象的属性来设置单元格的标签。

请阅读有关tableviews的教程。我推荐itunesU Paul Hegarty的讲座。他们真的很棒。

Ps。您在numberofrowsinsection中释放了bundleRoot对象,您不会保留(或完全使用)最有可能导致崩溃的对象。

编辑:

有了一点空闲时间,我润饰代码:

//code not tested/written in xcode. Might contain typos 

//in your .m file 
//in your (private) interface 

@property (nonatomic, retain, readonly) NSArray *dirContents; 

//in your implementation 

@synthesize dirContents=_dirContents; 

-(NSArray*) dirContents { 
    if (!dirContents) { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectoryPath = [paths objectAtIndex:0]; 
    _dirContents = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:nil] retain]; 
    } 
    return _dirContents; 
    //note that if you want to "refresh" the contents you would have to 
    //release _dirContents and set it to nil or implement this differently 
} 

-(void) dealloc { 
    [_dirContents release]; 
    //.... 
    [super dealloc]; 
} 


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    return [[self dirContents] count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    UITableViewCell *cell = nil; 

    cell = [tableView dequeueReusableCellWithIdentifier:@"MyCells"]; 
    if (cell == nil) { 
    cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyCells"]autorelease]; 
    } 

    cell.textLabel.text = [[self dirContents] objectAtIndex: indexPath.row]; 

    return cell; 
    //  NSLog(@"Did return"); //this never gets called by the way 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    NSLog(@"%@",cell.textLabel.text); 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 
0

确保在使用时不会释放dirContents。我确信您没有做,只是与您的代码进行交叉检查。