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

从外观上看,您只会泄漏内存,并且用自身替换字典条目的方式似乎不寻常(但我认为它应该有效),但是是什么让您认为您正在丢失对象?您正在打印数组的大小,这对于不同的日期字符串是不同的,所以也许您只是得到了一个新的日期字符串,使它为该日期创建了一个新数组?

关于内存泄漏/异常代码:更传统的方法是

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 回答
0

代码对我来说看起来不错(如果您包含来自@ConradShultz 的建议)

请注意,您不需要创建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 回答