1

私は自分のプロジェクトの1つである@imのパーセントエスケープのより良い実装で小さなNSStringカテゴリを作成しました

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

この1つのプロジェクトでは、それは素晴らしい働きをし、私はそれを使うのが大好きです。しかし、それを別のプロジェクトに移植すると、そのコードはEXC_BAD_ACCESSを介して行われます。そのコードで何かを改善できますか?

4

2 に答える 2

1

私は偶然に私の問題を見つけました:

1文字を3文字に置き換えると、文字列の長さが効果的に変わるため、置き換えるたびに文字列の長さが変わります。したがって、カテゴリの正しい実装は次のようになります。

@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
于 2012-08-07T11:40:04.693 に答える
0

私はそれがすべきだと思います:

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

replaceOccurrencesOfString:withString:options:range:メソッドが文字列の最後の文字を超えて繰り返されると、「不正なアクセス」が発生します。

または、このようなものを、全長にわたって反復することをすでに考えている置換方法に使用することもできます。ただし、デフォルトの検索オプションが何であるかはわかりません。

escaping = [escaping stringByReplacingOccurencesOfString:@"$" withString:@"%24"];
于 2012-07-31T21:49:17.713 に答える