NSMutableDictionary丢失对象

时间:2012-07-06 22:50:45

标签: objective-c osx-lion automatic-ref-counting nsdictionary

我正在尝试将对象数组存储在Mutable Dictionary中,但似乎字典丢失了一些我的数组(或者数组可能正在丢失数据?)。

无论如何,这就是我所在的地方:

- (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。

2 个答案:

答案 0 :(得分:0)

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

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

NSMutableArray *ticketArray = [datesDict objectForKey:dateString];
if (ticketArray == nil) {
      ticketArray = [[NSMutableArray alloc] init];
      [datesDict setObject:ticketArray forKey:dateString];
      [ticketArray release];
}
[ticketArray addObject:ticket];

答案 1 :(得分: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;
}