NSString类别用于更好地转义百分比

时间:2012-06-19 12:23:00

标签: encoding nsstring urlencode percent-encoding

我写了一个NSString类别,为我的一个项目更好地实现了百分比转义: @im

plementation NSString (Escaping)
- (NSString *)stringByAddingSafePercentEscapesUsingEncoding:(NSStringEncoding)encoding
{
    NSRange wholeString = NSMakeRange(0, [self length]);
    NSMutableString *escaping = [NSMutableString stringWithString:[self stringByAddingPercentEscapesUsingEncoding:encoding]];
    [escaping replaceOccurrencesOfString:@"$" withString:@"%24" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"&" withString:@"%26" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"," withString:@"%2C" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@";" withString:@"%3B" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"-" withString:@"%2D" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"=" withString:@"%3D" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"?" withString:@"%3F" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"@" withString:@"%40" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@" " withString:@"%20" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"\t" withString:@"%09" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"#" withString:@"%23" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"<" withString:@"%3C" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@">" withString:@"%3E" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"\"" withString:@"%22" options:NSCaseInsensitiveSearch range:wholeString];
    [escaping replaceOccurrencesOfString:@"\n" withString:@"%0A" options:NSCaseInsensitiveSearch range:wholeString];
    NSString *escaped = [NSString stringWithString:escaping];

    return escaped;
}
@end

在这个项目中,它很有效,我喜欢使用它。但当我将它移植到另一个项目时,该代码通过EXC_BAD_ACCESS。我可以在那段代码中做些更好的东西吗?

2 个答案:

答案 0 :(得分:1)

我偶然发现了我的问题:

由于字符串在将一个字符替换为三个字符时有效地改变了其长度,因此字符串长度随每次替换而变化。因此,该类别的正确实施将是:

@implementation NSString (Escaping)
- (NSString *)stringByAddingSafePercentEscapesUsingEncoding:(NSStringEncoding)encoding
{
    NSRange wholeString = NSMakeRange(0, [self length]);
    NSMutableString *escaping = [NSMutableString stringWithString:[self stringByAddingPercentEscapesUsingEncoding:encoding]];
    [escaping replaceOccurrencesOfString:@"$" withString:@"%24" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"&" withString:@"%26" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"," withString:@"%2C" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@";" withString:@"%3B" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"-" withString:@"%2D" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"=" withString:@"%3D" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"?" withString:@"%3F" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"@" withString:@"%40" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@" " withString:@"%20" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"\t" withString:@"%09" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"#" withString:@"%23" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"<" withString:@"%3C" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@">" withString:@"%3E" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"\"" withString:@"%22" options:NSCaseInsensitiveSearch range:wholeString];
    wholeString = NSMakeRange(0, [escaping length]);
    [escaping replaceOccurrencesOfString:@"\n" withString:@"%0A" options:NSCaseInsensitiveSearch range:wholeString];
    NSString *escaped = [NSString stringWithString:escaping];

    return escaped;
}
@end

答案 1 :(得分:0)

我认为应该是:

NSRange wholeString = NSMakeRange(0, [self length]-1);

如果您的replaceOccurrencesOfString:withString:options:range:方法迭代超过字符串中的最后一个字符,您将获得“访问不良”。

或者你可以使用这样的东西来替换已经在整个长度上迭代的替换方法。我不确定默认搜索选项是什么:

escaping = [escaping stringByReplacingOccurencesOfString:@"$" withString:@"%24"];