开发者

Organize objective-C string for filters

How can I organize this string better for best coding practices. It's a string that defines f开发者_StackOverflow中文版ilters:

NSString* string3 = [[[[[[tvA.text stringByReplacingOccurrencesOfString:@"\n" withString:@" "] stringByReplacingOccurrencesOfString:@"&" withString:@"and"] stringByReplacingOccurrencesOfString:@"garçon" withString:@"garcon"] stringByReplacingOccurrencesOfString:@"Garçon" withString:@"Garcon"] stringByReplacingOccurrencesOfString:@"+" withString:@"and"] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

Is there a way to have it be:

NSString* string3 = [[[[[tvA.text filter1] filter2] filter3] filter4] filter5] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];


You shouldn't be replacing & and + before percent-escaping. The problem is that stringByAddingPercentEscapesUsingEncoding: (IIRC) adds the minimum escapes to make it a "valid" URL string, whereas you want to escape anything that might have a special interpretation. For this, use CFURLCreateStringByAddingPercentEscapes():

return [(NSString*)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)aString, NULL, (CFStringRef)@":/?#[]@!$&'()*+,;=", kCFStringEncodingUTF8) autorelease];

This encodes & and + correctly, instead of just changing them to "and". It also encodes newlines as %0a (so you might want to replace them with spaces; that's your call), and encodes ç as %C3%A7 (which is decoded correctly if you use UTF-8 on the server).


The first thing I'd do is capture the transformation into a method somewhere (where "somewhere" is either an instance method on an appropriate object or a class method on a utility class).

- (NSString *) transformString: (NSString *) aString
{
    NSString *transformedString;

    transformedString = [aString stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
    transformedString = [transformedString stringByReplacingOccurrencesOfString:@"&" withString:@"and"];
    transformedString = [transformedString stringByReplacingOccurrencesOfString:@"garçon" withString:@"garcon"];
    transformedString = [transformedString stringByReplacingOccurrencesOfString:@"Garçon" withString:@"Garcon"];
    transformedString = [transformedString stringByReplacingOccurrencesOfString:@"+" withString:@"and"];
    transformedString = [transformedString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

    return transformedString;
}

Then:

NSString *result = [myTransformer transformString: tVA.text];

A bit brutish, but it'll work. And by "brutish", I mean that it is going to be slow and will cause a bunch of interim strings to pile up in the autorelease pool. However, if this is something that you only do every now and then, don't worry about it -- while brutish, it is certainly quite straightforward.

If, however, this shows up in performance analysis as a bottleneck, you could first move to using NSMutableString as it has methods for doing replacements in place. That, at least, will reduce memory thrash and will likely be a bit faster in that there is less copying of strings going on.

If that is still too slow, then you will likely need to write yourself a fun little bit of parsing and processing code that walks through the original and copies it to new a new string while also doing any necessary transforms along the way.

But, don't bother optimizing until you prove that it is a problem. And, of course, if it is a problem, you have just one method to optimize!


If performance is not crucial, put the strings and their replacements into an NSDictionary and iterate over the items. Put it all in a helper method and use a NSMutableString to work on it (which reduces at least some of the cost).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜