views:

45769

answers:

7

Are there any shortcuts to (stringByAppendingString:) string concatenation in Objective-C or shortcuts for working with NSString or other objects in general?

e.g. I'd like to make this:

NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];

something more like this:

string myString = "This";
string test = myString + " is just a test";
+13  A: 

Two answers I can think of... neither is particularly as pleasant as just having a concatenation operator.

First, use an NSMutableString, which has an appendString method, removing some of the need for extra temp strings.

Second, use an NSArray to concatenate via the componentsJoinedByString method.

Chris Blackwell
Although the other option has many upvotes, I think this is the best answer if you don't know all your strings upon construction. Every time you append a string, you're creating a lot of overhead. Using a mutable string removes that problem.
Eli
+1 Agree w @Eli. These are generally the best solutions. NSArray -componentsJoinedByString can be done in a single line pretty well: string = [[NSArray arrayWithObjects:@"This", "Is", "A", "Test", nil] componentsJoinedByString:@" "];
Rob Napier
+1  A: 

The only way to make c = [a stringByAppendingString: b] any shorter is to use autocomplete at around the st point. The + operator is part of C, which doesn't know about Objective-C objects.

Graham Lee
+53  A: 

I'm guessing you're not happy with multiple appends (a+b+c+d), in which case you could do:

NSLog(@"%@", [Util append:one, @" ", two, nil]); // "one two"
NSLog(@"%@", [Util append:three, @"/", two, @"/", one, nil]); // three/two/one

using something like

+ (NSString *) append:(id) first, ...
{
    NSString * result = @"";
    id eachArg;
    va_list alist;
    if(first)
    {
     result = [result stringByAppendingString:first];
     va_start(alist, first);
     while (eachArg = va_arg(alist, id)) 
      result = [result stringByAppendingString:eachArg];
     va_end(alist);
    }
    return result;
}

but you'd get the same result using:

[NSString stringWithFormat:@"%@/%@/%@", three, two, one];
diciu
+1 for the simple stringWithFormat solution
dbr
Your second solution is a lot nicer :)
pablasso
@pablasso Agreed. The Util method is pretty ugly. If you wanted such a thing, it should be done as a NSString category with a name like +stringByAppendingStrings:. Even a straight-up function with a name like NSStringForAppendedStrings(...) would be better than a static method in a class like Util (anything with "Util" in the name is likely poorly factored). The function is also better implemented with an NSMutableString and -appendString to avoid creating an unbounded set of temporary autoreleased NSStrings.
Rob Napier
A: 
NSString *label1 = @"Process Name: ";
NSString *label2 = @"Process Id: ";
NSString *processName = [[NSProcessInfo processInfo] processName];
NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
NSString *testConcat = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
+4  A: 

Shortcut by creating AppendString (AS) macro ...

#define AS(A,B)    [(A) stringByAppendingString:(B)]
NSString *myString = @"This"; NSString *test = AS(myString,@" is just a test");
Cool! I still think the Util above is a much more elegant solution; you can append only one string with this macro, right?
Typeoneerror
True, the AS macro above does one append per line of code. If multiple appends are a common need, then more macros can be created. For example, a macro to append two strings:<pre>#define A2S(A,B,C) [[(A) stringByAppendingString:(B)] stringByAppendingString:(C)]</pre>
Or, simply shorten the typing required with a macro like "#define AS stringByAppendingString", then just use "AS" where your would normally type "stringByAppendingString", and enjoy multiple appends per line of code.
woo this helped me, and i don't even know objective-c!
tarnfeld
The problem with these macros is that they undermine one of the major goals of Objective-C, which is readability. It's extremely unclear what "AS" does. Saving a few keystrokes (most of which are handled with autocompletion) at the expense of readability is seldom a good trade-off. There are exceptions (the @"" syntax is much more readable than having to use +stringWithUTF8String: every time), but the goal should still be readability rather than simply brevity. You write once, but you debug forever.
Rob Napier
A: 
NSString *label1 = @"Process Name: ";
NSString *label2 = @"Process Id: ";
NSString *processName = [[NSProcessInfo processInfo] processName];
NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
NSString *testConcat = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
venky284
A: 

Use this way


NSString *string1,*string2,result;

string1 = @"This is ";
string2 = @"my string.";
result = [NSString alloc];

result = [result stringByAppendingString:string1];
result = [result stringByAppendingString:string2];
 OR

result = [result stringByAppendingString:@"This is "];
result = [result stringByAppendingString:@"my string."];
T. A.