2013-08-19 2 views
3

J'utilise le code suivant pour créer un NSDate à partir d'un format spécifique d'un NSString.dateFromString: crash Objectif 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]; 
} 

Chaque fois dans une lune bleue, je vais recevoir un EXC_BAD_ACCESS sur return [formatter dateFromString:cleaned]; Affichage des spectacles de trace de pile qui nettoyés, dateString et formatter ont toutes leurs valeurs correctes (non nul et « po » imprime une valeur correcte dans la console). Après avoir lu, j'ai découvert que mon code doit prendre en compte la sécurité des threads sur NSDateFormatter. (Et j'ai correctement ajusté mon code qui n'est pas montré ici.) Cependant selon les traces de pile, un seul thread accède à mon NSDateFormatter quand le crash s'est produit.

La trace de la pile à l'exception de l'aspect ci-dessous.

#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:] 
... 

Quelqu'un at-il rencontré quelque chose comme ça avant et a des conseils pour le débogage?

Répondre

0

approche Debugging serait comme ceci:

+ (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]; 
} 

Notez que le format doit être conforme à celui described here. Pour plus de référence, lire this.

MISE À JOUR:

objets comme NSDateFormatter sont mieux conservés singleton. Et c'est ce que votre objectif original semble être - de votre allocateur statique et allocation synchronisée. Lorsque vous le commandez pour créer un nouvel objet à chaque fois avec un bloc de synchronisation, il est probable que le cacao gâche des choses.

Voici comment vous le faites:

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

Bon point de départ, mais aucune des valeurs sont nulles et formatter est conforme à un format approprié. Cet accident apparaît bizarrement seulement une fois par semaine. Je l'ai attrapé aujourd'hui et vérifié tout cela à partir de la console. Encore plus intéressant, j'ai tapé 'po [formatter dateFromString: nettoyé]' dans la console et il a retourné la sortie que l'appelant attendait à l'origine. –

+0

Étrange. Essayez NSZombie? –

+0

Voir ma réponse mise à jour. –