views:

124

answers:

3

Both work, but... Which one would you use and why ?

@implementation NSString (Extender)

    -(NSString *) stringByTrimmingPrefix:(NSString *)strPrefix 
    {
        while ([self hasPrefix:strPrefix]) 
        {
            self = [self substringFromIndex:strPrefix.length];
        }
        return self;
    }

@end

or

@implementation NSString (Extender)

    -(NSString *) stringByTrimmingPrefix:(NSString *)strPrefix 
    {
        NSString *returnValue = [NSString stringWithString:self];
        while ([returnValue hasPrefix:strPrefix]) 
        {
            returnValue = [returnValue substringFromIndex:strPrefix.length];
        }
        return returnValue;
    }

@end
A: 

so this just chops off a single letter from the front of a string (if that letter is there more than once, it will cut off as many as there are)?

Since NSString is immutable, I don't there is a difference either way, performance wise. In the first case you are replacing self with a new string object each time, and in the second case, you are replacing returnValue with a new string object each time. I guess since the first option saves a line of code i would use that one.

darren
+4  A: 

Option #2.

NSString is intended to be an immutable object. All of the standard "stringBy" methods on NSString return new autoreleased NSStrings.

While #1 also ends up returning a new NSString, it is at best semantically incorrect and at worst altering the referenced object of what was supposed to be an immutable object.

rcw3
Actually, there isn't anything wrong with option #1. 'self' is not a member variable, it is a simple function parameter. You can assign 'self' to anything you want, it doesn't change the state if the object it was originally pointing to.
Darren
Although technically it works, I think it's really bad form and would confuse a lot of people.
Kendall Helmstetter Gelner
calling context in 'self' and you are modifying the self object is not a good programming practice.
Girish Kolari
Ok, so, it does function. I'll go with just semantically incorrect...
rcw3
+2  A: 

Firstly, your Objective-C method definition is exactly equivalent to this C function:

NSString* stringByTrimmingPrefix(NSString* self, SEL _cmd, NSString* strPrefix)
{
    ...
}

As you can see, self is just another function parameter; you can re-assign it to anything you want and it won't affect the state of the original NSString* instance it was originally pointing to.

So there's nothing wrong with what you're doing in your first implementation, in that respect.

However, neither of your implementations are very efficient, and both have bugs (what happens if you pass a prefix with more than one character?)

I would use rangeOfString:options:range: to find your prefixes, so that you're only creating at most one extra NSString instance.

See Searching, Comparing, and Sorting Strings

Darren