형식 문자열을 사용하여 URL의 경로 부분을 쉽게 설정할 수있는 방법을 작성했습니다. 원래 형식 문자열과 args를 initWithFormat:
에 직접 전달했지만 누군가 나를 통해 전달되는 공백을 args로 전달합니다. initWithFormat:
로 가기 전에 메서드를 백분율로 변경했습니다.이 varargs 함수는 어떻게 안전하게 처리 할 수 있습니까?
[request setUrlWithFormat:@"users/%@/timesheets", username]
과 같이 지정할 수 있습니다. username
은 bmauter
또는 b mauter
일 수 있습니다.
- (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];
}
때때로 나는 처음
for
루프 라인에 EXC_BAD_ACCESS와 충돌. 때로는
initWithString:
행에서 충돌이 발생합니다. 대부분의 경우 완벽하게 작동합니다.
업데이트 : 감사합니다. @uliwitness. 다른 사람이 내가 뭘했는지보고 싶다면 여기로 가십시오 :
- (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];
}
감사합니다. 제가 게시 한 직후, 형식 지정자의 수를 계산해야한다는 것을 알았습니다. 그것을 알면 지금까지 발견 된 모든 충돌을 첫 번째'for' 루프에서 해결합니다. 나는 여전히 두 번째'for' 루프 크래시에 붙어 있습니다. 이 코드는 'NSArray'를 varargs 목록에 패키지화하려고합니다. 나는 그 코드를 여기에서 찾아서 내 목적에 맞게 조정했다. 이상적으로는'NSString'은 메소드의 타입 인'initWithFormat : argsInArray'를 가질 것입니다. 나는 그것이 일어날 때까지 형식 지정자를 독자적으로 바꾸어야 할 것이라고 당신이 맞다고 생각합니다. – bmauter