2012-07-06 112 views
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