Ich habe eine Methode geschrieben, die es einfach macht, den Pfad-Teil einer URL mit Formatzeichenfolgen festzulegen. Ursprünglich habe ich nur die Formatzeichenfolge und Argumente direkt in initWithFormat:
übergeben, aber jemand, der mich übergibt, argumentiert mit Leerzeichen innerhalb. Ich änderte die Methode, um die Argumente in Prozent zu kodieren, bevor ich zu initWithFormat:
ging.Wie kann ich diese varargs Funktion sicher handhaben?
Ich könnte es wie [request setUrlWithFormat:@"users/%@/timesheets", username]
, wo username
könnte bmauter
oder b mauter
sein.
- (void) setUrlWithFormat:(NSString *)format, ... {
// loop through varargs and cleanse them for the URL path
va_list args;
va_start(args, format);
NSMutableArray *cleaned = [[NSMutableArray alloc] init];
for(NSString *s = format; s != nil; s = va_arg(args, NSString *)) {
if (s == format) continue;
[cleaned addObject:[s stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]];
}
va_end(args);
// put the cleansed values back into a varargs list
__unsafe_unretained id *argList = (__unsafe_unretained id *) calloc(1UL, sizeof(id) * cleaned.count);
for (NSInteger i = 0; i < cleaned.count; i++) argList[i] = cleaned[i];
NSString* result = [[NSString alloc] initWithFormat:format, *argList];
free(argList);
[self setUrl:result];
}
Manchmal mit einem EXC_BAD_ACCESS auf der ersten for
Loopleitung ich zum Absturz bringen. Manchmal stürze ich auf die initWithString:
Linie. Meistens funktioniert es perfekt.
Update: Danke wieder @uliwitness. Falls jemand will sonst sehen, was ich am Ende mit auf, geht hier:
- (void) setUrlWithFormat:(NSString *)format, ... {
DLog(@"format=%@", format);
va_list args;
va_start(args, format);
NSMutableString *result = [format mutableCopy];
NSRange range = [result rangeOfString:@"%@"];
while(range.location != NSNotFound) {
NSObject *obj = va_arg(args, NSObject *);
NSString *dirty = nil;
if ([obj isKindOfClass:[NSString class]]) dirty = (NSString *)obj;
else dirty = [NSString stringWithFormat:@"%@", obj];
NSString *clean = [dirty stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
DLog(@"dirty=%@, clean=%@", dirty, clean);
[result replaceCharactersInRange:range withString:clean];
range = [result rangeOfString:@"%@"];
}
va_end(args);
DLog(@"result=%@", result);
[self setUrl:result];
}
Vielen Dank, Sie haben Recht. Kurz nachdem ich gepostet hatte, fand ich heraus, dass ich die Anzahl der Formatspezifizierer zählen sollte. Zu wissen, dass alle Abstürze, die ich bisher gefunden habe, auf der ersten "for" -Schleife gelöst werden. Ich stehe immer noch auf dem zweiten 'for' Loop-Crash. Dieser Code versucht, ein 'NSArray' in eine Varargs-Liste zu packen. Ich habe diesen Code hier auf SO gefunden und für meine Zwecke optimiert. Im Idealfall hätte 'NSString' einen' initWithFormat: argsInArray': Typ der Methode. Ich nehme an, du hast auch recht, dass ich bis dahin die Formatspezifizierer einfach selbst ersetzen muss. – bmauter