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).
精彩评论