1

オブジェクトの配列を可変ディクショナリに格納しようとしていますが、ディクショナリが配列の一部を失っているようです (または、配列がデータを失っているのでしょうか?)。

とにかく、ここにいる:

- (NSDictionary *)getTicketsByDay:(NSArray *)tickets {
    // take an array of tickets and return a dictionary with dates (given by
    // NSDateFormatterShortStyle) as keys and arrays of tickets as the values

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterShortStyle];

    // get NSDate object without time (only month, day, year)
    unsigned int flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSMutableDictionary *datesDict = [[NSMutableDictionary alloc] init];

   for (Ticket *ticket in tickets) {
        NSDateComponents *ticketDateNoTimeComponents = [calendar components:flags fromDate:[ticket createdAt]];
        NSDate *ticketDateNoTime = [calendar dateFromComponents:ticketDateNoTimeComponents];
        NSString *dateString = [formatter stringFromDate:ticketDateNoTime];
        NSMutableArray *ticketArray = [datesDict objectForKey:dateString];
        NSLog(@"%lu", [ticketArray count]);
        if (ticketArray == nil) {
            NSLog(@"it's here: %@", dateString);
            ticketArray = [[NSMutableArray alloc] init];
        }
        [ticketArray addObject:ticket];
        NSLog(@"%lu", [ticketArray count]);
        [datesDict setObject:ticketArray forKey:dateString];
     }
     return datesDict;
}

しかし、コンソールでは、ランダムな場所で(毎回同じ場所ですが)、次のような結果が得られます

41
41
42
0
it's here: 6/29/12
1

以前のオブジェクトのキーも「6/29/12」でしたが。また、辞書のすべてのキーを出力しましたが、1つしかありません。

そのため、どこかでデータが失われています。どうしたの?

また、私は 10.7.4 で ARC を使用していることにも言及する必要があります。

4

2 に答える 2

0

コードは私には問題ないように見えます(@ConradSultzからの提案を含める場合)

日付形式を使用しているため、 ticketDateNoTime を作成する必要がないことに注意してください。日付に時間が含まれている場合でも、常に短い形式の文字列が生成されます...

したがって、コードは次のように簡略化できます。

- (NSDictionary *)getTicketsByDay:(NSArray *)tickets {
    // take an array of tickets and return a dictionary with dates (given by
    // NSDateFormatterShortStyle) as keys and arrays of tickets as the values

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterShortStyle];

    NSMutableDictionary *datesDict = [[NSMutableDictionary alloc] init];

    for (Ticket *ticket in tickets) {
        NSString *dateString = [formatter stringFromDate:[ticket createdAt]];
        NSMutableArray *ticketArray = [datesDict objectForKey:dateString];
        NSLog(@"%lu", [ticketArray count]);
        if (ticketArray == nil) {
           NSLog(@"it's here: %@", dateString);
            ticketArray = [[NSMutableArray alloc] init];
            [datesDict setObject:ticketArray forKey:dateString];
        }
        [ticketArray addObject:ticket];
        NSLog(@"%lu", [ticketArray count]);
    }
    return datesDict;
}
于 2012-07-07T02:44:21.103 に答える
0

見た目からすると、メモリをリークするだけで、辞書エントリをそれ自体で置き換える方法は珍しいように思えます (しかし、うまくいくはずです)。日付文字列ごとに異なる配列のサイズを出力しているので、新しい日付文字列を取得して、その日付の新しい配列を作成したのではないでしょうか?

そして、メモリリーク/異常なコードについて:より伝統的な方法は

NSMutableArray *ticketArray = [datesDict objectForKey:dateString];
if (ticketArray == nil) {
      ticketArray = [[NSMutableArray alloc] init];
      [datesDict setObject:ticketArray forKey:dateString];
      [ticketArray release];
}
[ticketArray addObject:ticket];
于 2012-07-06T23:06:00.623 に答える