1

我想将对象的数组存储在可变的字典中,但它好像字典丢失了我的一些数组(或者也许数组正在丢失数据?)。NSMutableDictionary丢失对象

不管怎么说,这里是我在哪里:

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

+0

“丢失我的数据”是什么意思?输出看起来像我期望的代码。 – 2012-07-06 23:03:05

+1

顺便说一句,在后续的迭代中你不需要使用'[datesDict setObject:]' - 你已经在原地改变了数组,所以你现在只是在旋转CPU周期。 – 2012-07-06 23:03:59

+0

@ConradShultz对不起,我应该澄清。之前的对象也有一个“6/29/12”的日期,所以它们应该在同一个数组中,但它重置为0.然后,如果我打印出字典中的所有关键字,那么只有一个键。我编辑了我的问题来反映这一点。 – 2012-07-06 23:08:39

回答

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; 
} 
+0

我还在学习Objective-C,所以我尝试了你的代码,2个简单的“Ticket”对象与createdAt = [NSDate日期] - 我得到0;它在这里:7/07/12; 1; 1; 2 – MattR 2012-07-07 02:56:03

+0

感谢您删除不必要的代码。该函数工作正常,但我很累,我遇到的问题是在函数调用中,而不是函数本身。 – 2012-07-08 12:59:42

0

从外观上看,你只会泄漏内存,你用自己替换字典条目的方式看起来很不寻常(但我认为它应该可行),但是什么让你觉得你失去了对象呢?你正在打印你的数组的大小,对于不同的日期字符串是不同的,所以也许你刚刚得到一个新的日期字符串,这使得它创建一个新的数组在那个日期?

而且对内存泄漏/异常代码:一个更传统的方式是

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

这个问题被标记为自动引用计数,所以我会假设OP正在使用ARC。所以泄漏应该不成问题。我同意替换字典条目的评论(请参阅上面的评论)。 – 2012-07-06 23:08:12

+0

我确实提到过我使用ARC,并且我已将代码更改为您和@ConradShultz建议的方法。 – 2012-07-06 23:16:37