2013-03-26 78 views
2

我会想'self.data ='会保留autorelease NSMutableArray对象和它包含的NSMutableDictionary对象,但是当表格的cellForRowAtIndexPath方法试图访问self.data中的NSDictionaries时,我最终得到EXC_BAD_ACCESS。是否将autorelease对象分配给保留属性会增加其保留数?

@property (strong, nonatomic) NSMutableArray *data; 

- (void) updateReceivedData:(NSData *) jsonData 
{ 
    NSMutableArray *fetchedData = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; 
     self.data = [self convertDates:fetchedData withFormat:kMySQLDateTimeFormat]; 
     [self.tableView reloadData]; 
    } 
} 

- (NSMutableArray*) convertDates:(NSMutableArray *) array withFormat:(NSString *) format 
{ 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateFormat:format]; 
    NSMutableArray *newArray = [NSMutableArray arrayWithArray:array]; 
    for (NSMutableDictionary *dict in newArray) 
    { 
     for (id key in dict.allKeys) 
     { 
      if ([[dict objectForKey:key] isKindOfClass:[NSString class]]) 
      { 
       NSString *value = [dict objectForKey:key]; 
       NSDate *date = [dateFormatter dateFromString:value]; 
       if (date) [dict setObject:date forKey:key]; 
      } 
     } 
    } 
    [dateFormatter release]; 
    return newArray; 
} 

BAD_ACCESS HERE在NSLog之间抛出这里。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"cell"; 
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     NSLog (@"Cell was nil"); 
     cell = [[[CustomCell alloc] init] autorelease]; 
    } 

    NSDictionary *dict = [[NSDictionary alloc] init]; 
    if (_isFiltered){ 
     dict = [self.filteredData objectAtIndex:indexPath.row]; 
    } else { 
     dict = [self.data objectAtIndex:indexPath.row]; 
    } 
    NSLog (@"Filling Label 1"); 
    cell.IDLabel.text = [[dict objectForKey:@"Id"] stringValue]; 
    NSLog (@"Filling Label 2"); 
    cell.firstNameLabel.text = [dict objectForKey:@"firstName"]; 
    [dict release]; 
    return cell; 
} 
+0

在什么行会引发异常? – 2013-03-26 23:34:55

+0

添加'-cellForForAtIndexPath'代码来提问。 – TijuanaKez 2013-03-26 23:50:45

+0

假设您在属性声明中使用'strong',那么'self.data = foo'将保留该对象。但是,这并没有阻止其他代码在太多时间释放它。最有可能的事情应该释放对象*一次*实际上释放它*两次*。我建议启用ARC而不是尝试查找问题,这很容易。 – 2013-03-27 00:57:42

回答

5

打开僵尸,看看它是否抓住了问题(EXC_BAD_ACCESS并不一定意味着过度释放的对象,但它可能)。

对象的保留计数的绝对值无关紧要。

但是,strong属性意味着该对象被保留,是的,如果您通过setter(即self.data = ...而不是_data = ...)进行分配。

+0

感谢nkongara发现我的代码错误。然而,这是正确的答案。 – TijuanaKez 2013-03-28 01:53:27

2

你为什么要在cellForRowAtIndexPath中释放字典:尽管你分配字典,你正在分配另一个指针,这是来自filteredData或数据的对象。只要删除[数据发布],同时声明数据分配为零

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"cell"; 
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     NSLog (@"Cell was nil"); 
     cell = [[[CustomCell alloc] init] autorelease]; 
    } 

    // **As you will be assigning the object from filteredData/data, don't allocate here** 
    NSDictionary *dict = nil; 
    if (_isFiltered){ 
     dict = [self.filteredData objectAtIndex:indexPath.row]; 
    } else { 
     dict = [self.data objectAtIndex:indexPath.row]; 
    } 
    NSLog (@"Filling Label 1"); 
    cell.IDLabel.text = [[dict objectForKey:@"Id"] stringValue]; 
    NSLog (@"Filling Label 2"); 
    cell.firstNameLabel.text = [dict objectForKey:@"firstName"]; 
    // **Release not required as you didn't allocate** 
    //[dict release]; 
    return cell; 
} 
+1

这正是问题所在。你发布的'dict'对象与你分配的不一样。 – 2013-03-27 00:51:24

+0

谢谢,我其实只是想出了这个解释欢呼。 Origionally我创造了'NSDictionary * dict = [self.data objectAtIndex:indexPath.row];'但是当我添加if语句时,编译器说'dict'未被声明。我忘了宣布为零。我想技术上来说bbum是这个问题的正确答案。 – TijuanaKez 2013-03-27 01:15:38

相关问题