2013-08-19 43 views
3

我使用以下代碼從NSString的特定格式創建NSDate。dateFromString:crash目標C

+ (NSDateFormatter *)serverFormatter 
{ 
    static NSDateFormatter *formatter = nil; 

    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     formatter = [[NSDateFormatter alloc] init]; 
     [formatter setDateFormat:@"yyyy-MM-dd'T'HHmmssZ"]; 
    }); 

    return formatter; 
} 

+ (NSDate *)dateFromServerDateString:(NSString *)dateString 
{ 
    if (!dateString) { 
     return nil; 
    } 

    NSDateFormatter *formatter = [NSDate serverFormatter]; 
    NSString *cleaned = [dateString stringByReplacingOccurrencesOfString:@":" 
                  withString:@""]; 

    return [formatter dateFromString:cleaned]; 
} 

每過一個藍色的月亮,我會在return [formatter dateFromString:cleaned];收到EXC_BAD_ACCESS查看堆棧跟蹤顯示,清潔,dateString和格式都具有其正確的價值觀(不是零和「寶」打印正確的值在控制檯中)。

做了一些閱讀後,我發現我的代碼需要考慮NSDateFormatter上的線程安全性。 (我已經適當地調整了我的代碼,這裏沒有顯示。)但是根據堆棧跟蹤,發生崩潰時只有一個線程正在訪問我的NSDateFormatter。

具有異常的堆棧跟蹤如下所示。

#0 0x02d09ad1 in typeinfo name for icu::UObject() 
#1 0x02b8f5ed in icu::TimeZone::getOffset(double, signed char, int&, int&, UErrorCode&) const() 
#2 0x02b95652 in icu::Calendar::computeTime(UErrorCode&)() 
#3 0x02b95552 in icu::Calendar::updateTime(UErrorCode&)() 
#4 0x02b96036 in icu::Calendar::getTimeInMillis(UErrorCode&) const() 
#5 0x02c4244f in icu::DateFormat::parse(icu::UnicodeString const&, icu::ParsePosition&) const() 
#6 0x02cebd05 in udat_parse() 
#7 0x029b7161 in CFDateFormatterGetAbsoluteTimeFromString() 
#8 0x029b6f8e in CFDateFormatterCreateDateFromString() 
#9 0x0214e7e9 in getObjectValue() 
#10 0x0214e701 in -[NSDateFormatter getObjectValue:forString:errorDescription:]() 
#11 0x0214ea3f in -[NSDateFormatter dateFromString:]() 
#12 0x0001a7a4 in +[NSDate(RDUtilities) dateFromServerDateString:] 
... 

有沒有人遇到過這樣的事情,並有調試任何提示?

回答

0

調試的方法是這樣的:

+ (NSDate *)dateFromServerDateString:(NSString *)dateString 
{ 
    if (!dateString) { 
     return nil; 
    } 
    NSLog (@"%@", dateString); 
    NSDateFormatter *formatter = [NSDate serverFormatter]; 
    NSString *cleaned = [dateString stringByReplacingOccurrencesOfString:@":" 
                  withString:@""]; 
    NSLog (@"%@", cleaned); //see if cleaned represents proper string with separators 
    NSLog (@"%@", formatter); //not null? 

    return [formatter dateFromString:cleaned]; 
} 

請注意,您的格式必須符合一個described here。 如需進一步參考,請閱讀this

UPDATE:

對象,如NSDateFormatter最好保持單身。這就是你的原始目標似乎是 - 從你的靜態分配器和同步分配。當你每次使用同步塊命令它創建新對象時,可能可能會讓事情變得糟糕。

這裏是你如何做到這一點:

+ (NSDateFormatter *)serverFormatter 
{ 
    static NSDateFormatter *formatter = nil; 

    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     if (formatter == nil) { 
     formatter = [[NSDateFormatter alloc] init]; 
     } 
     [formatter setDateFormat:@"yyyy-MM-dd'T'HHmmssZ"]; 
    }); 

    return formatter; 
} 
+0

很好的起點,但是,沒有一個值是零和格式符合到正確的格式。這個崩潰奇怪的只是一個星期左右出現一次。我今天抓到了它,並從控制檯中檢查了所有這些。更有趣的是,我在控制檯中輸入了'po [formatter dateFromString:cleared]',它返回了調用者最初期望的輸出。 –

+0

奇怪。試試NSZombie? –

+0

查看我更新的答案。 –