views:

981

answers:

2

I have a NSString that I need to examine character by character and:

 examine char
    perform calculation
 loop (until string ends)

Any thoughts on the best way to do this? Do I need to convert the NSString to a NSArray or C string?

+5  A: 

The simplest way to go about it is using NSString's characterAtIndex: method:

int charIndex;
for (charIndex = 0; charIndex < [myString length]; charIndex++)
{
    unichar testChar = [myString characterAtIndex:charIndex];
    //... your code here
}
e.James
Thanks! That does the trick.
Alan
+2  A: 

-characterAtIndex: is the simplest approach, but the best is to drop down to CFString and use a CFStringInlineBuffer, as in this method:

- (NSIndexSet *) indicesOfCharactersInSet: (NSCharacterSet *) charset
{
    if ( self.length == 0 )
    return ( nil );

    NSMutableIndexSet * set = [NSMutableIndexSet indexSet];

    CFIndex i = 0;
    UniChar character = 0;
    CFStringInlineBuffer buf;
    CFStringInitInlineBuffer( (CFStringRef)self, &buf, CFRangeMake(0, self.length) );

    while ( (character = CFStringGetCharacterFromInlineBuffer(&buf, i)) != 0 )
    {
        if ( [charset characterIsMember: character] )
            [set addIndex: i];

        i++;
    }

    return ( set );
}

This is better because it will grab a number of characters at once, fetching more as required. It's effectively the string-character version of for ( id x in y ) in ObjC 2.

Jim Dovey
Although the code is more complex, bonus points for taking advantage of NSString/CFString toll-free bridging! I think your suggestion is more space efficient, whereas is slightly more time efficient, due to fewer function calls. However, it would be a close race and the difference is probably minimal.
Quinn Taylor
It generally winds up being faster because it'll move a chunk of data at once, all of which can sit inside cache memory. The -characterAtIndex: version may well have to hit main memory much more often. It also enables better loop unrolling and similar compiler optimizations, because all the methods are inlined, giving the compiler the opportunity to optimize based on the specifics of the CFStringInlineBuffer function implementations.
Jim Dovey