2013-03-26 102 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

相關問題