2013-03-26 8 views
2

'self.data ='는 autorelease NSMutableArray 객체와 NSMutableDictionary 객체가 포함되어 있다고 생각했지만 결국 테이블의 cellForRowAtIndexPath 메소드가 self.data의 NSDictionaries에 액세스하려고하면 EXC_BAD_ACCESS가 발생합니다.유지 된 속성에 자동 회수 객체를 할당하면 보관 횟수가 늘어 납니까?

@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; 
} 

여기 NSLogs 사이에 BAD_ACCESS가 throw됩니다.

좀비에
- (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

예외가 발생하는 예외는 무엇입니까? –

+0

질문에 '-cellForForAtIndexPath'코드를 추가했습니다. – TijuanaKez

+0

속성 선언에서'strong'을 사용한다고 가정하면'self.data = foo'는 객체를 유지합니다. 그러나 다른 곳에서 다른 코드가 너무 많이 공개되는 것을 막을 수는 없습니다. 오브젝트를 한 번 릴리스해야 할 가능성이 높습니다. 실제로 한 번 * 두 번 릴리스합니다. 문제를 찾기보다는 ARC를 사용하는 것이 더 쉽습니다. –

답변

5

를 켜고 문제를 잡으면 (EXC_BAD_ACCESS는 반드시 이상 출시 된 개체를 의미하지 않는다, 그러나 수도)를 참조하십시오.

개체의 보유 수의 절대 값은 어떻게 되나요?

그러나 strong 속성은 설정자 (예 : self.data = ...가 아니라 _data = ...)를 통해 할당하면 개체가 유지된다는 것을 의미합니다.

+0

내 코드 오류를 발견 한 덕분에 nkongara에게 감사드립니다. 그러나 이것은 정답입니다. – TijuanaKez

2

왜 cellForRowAtIndexPath에 dict을 출시하고 있습니까? 당신이 dict을 할당하더라도, 당신은 filteredData 또는 데이터로부터의 객체 인 다른 포인터를 할당하고있다. [데이터 릴리스]를 제거하고 데이터를 선언 할 때 nil로 할당하십시오.

- (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' 객체는 할당 한 것과 다릅니다. –

+0

감사합니다. 실제로 설명에 대한 환호성을 알았습니다. Origionally 나는 그것을 'NSDictionary * dict = [self.data objectAtIndex : indexPath.row];로 만들었습니다. 하지만 if 문을 추가하면 컴파일러에서 'dict'이 선언되지 않았다고 말합니다. 나는 선언하지 않았다는 것을 잊었다. 나는 기술적으로 bbum의 질문에 대한 정답이라고 생각합니다. – TijuanaKez