2

'self.data ='は自動解放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;
}

ここでは、NSLogの間にBAD_ACCESSがスローされます。

- (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;
}
4

2 に答える 2

5

ゾンビをオンにして、問題が発生するかどうかを確認します(EXC_BAD_ACCESSは、必ずしも過剰にリリースされたオブジェクトを意味するわけではありませんが、問題が発生する可能性があります)。

オブジェクトの保持カウントの絶対値に何が起こるかは関係ありません。

ただし、strongプロパティは、セッターを介して割り当てる場合(つまり、_data =...ではなくself.data=...)、オブジェクトが保持されることを意味します。

于 2013-03-26T23:33:51.530 に答える
2

cellForRowAtIndexPathでdictをリリースするのはなぜですか。dictを割り当てても、filteredDataまたはdataからのオブジェクトである別のポインターを割り当てています。[データリリース]を削除し、データを宣言するときに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;
}
于 2013-03-27T00:44:01.600 に答える