MAO-EYE
2009-02-04 06:26
采纳率: 0%
浏览 565

Objective-c 中用于连接 NSStrings 的捷径

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

For example, I'd like to make:

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

something more like:

string myString = "This";
string test = myString + " is just a test";

转载于:https://stackoverflow.com/questions/510269/shortcuts-in-objective-c-to-concatenate-nsstrings

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

29条回答 默认 最新

  • python小菜 2009-02-04 06:44
    已采纳

    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.

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • 叼花硬汉 2009-02-04 07:25

    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.

    评论
    解决 无用
    打赏 举报
  • 北城已荒凉 2009-02-04 07:53

    An option:

    [NSString stringWithFormat:@"%@/%@/%@", one, two, three];
    

    Another option:

    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;
    }
    
    评论
    解决 无用
    打赏 举报
  • Memor.の 2009-06-20 17:38
    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];
    
    评论
    解决 无用
    打赏 举报
  • elliott.david 2009-07-18 05:38

    Shortcut by creating AppendString (AS) macro ...

    #define AS(A,B)    [(A) stringByAppendingString:(B)]
    NSString *myString = @"This"; NSString *test = AS(myString,@" is just a test");

    Note:

    If using a macro, of course just do it with variadic arguments, see EthanB's answer.

    评论
    解决 无用
    打赏 举报
  • 10.24 2010-06-10 09:50
    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];
    
    评论
    解决 无用
    打赏 举报
  • ~Onlooker 2010-07-26 16:04

    Use this way:

    NSString *string1, *string2, *result;
    
    string1 = @"This is ";
    string2 = @"my string.";
    
    result = [result stringByAppendingString:string1];
    result = [result stringByAppendingString:string2];
    

    OR

    result = [result stringByAppendingString:@"This is "];
    result = [result stringByAppendingString:@"my string."];
    
    评论
    解决 无用
    打赏 举报
  • 狐狸.fox 2011-03-17 11:59

    If you have 2 NSString literals, you can also just do this:

    NSString *joinedFromLiterals = @"ONE " @"MILLION " @"YEARS " @"DUNGEON!!!";
    

    That's also useful for joining #defines:

    #define STRINGA @"Also, I don't know "
    #define STRINGB @"where food comes from."
    #define JOINED STRINGA STRINGB
    

    Enjoy.

    评论
    解决 无用
    打赏 举报
  • from.. 2011-03-23 17:37

    This is for better logging, and logging only - based on dicius excellent multiple argument method. I define a Logger class, and call it like so:

    [Logger log: @"foobar ", @" asdads ", theString, nil];
    

    Almost good, except having to end the var args with "nil" but I suppose there's no way around that in Objective-C.

    Logger.h

    @interface Logger : NSObject {
    }
    + (void) log: (id) first, ...;
    @end
    

    Logger.m

    @implementation Logger
    
    + (void) log: (id) first, ...
    {
        // TODO: make efficient; handle arguments other than strings
        // thanks to @diciu http://stackoverflow.com/questions/510269/how-do-i-concatenate-strings-in-objective-c
        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);
        }
        NSLog(@"%@", result);
    }
    
    @end 
    

    In order to only concat strings, I'd define a Category on NSString and add a static (+) concatenate method to it that looks exactly like the log method above except it returns the string. It's on NSString because it's a string method, and it's static because you want to create a new string from 1-N strings, not call it on any one of the strings that are part of the append.

    评论
    解决 无用
    打赏 举报
  • YaoRaoLov 2011-10-03 22:29

    create a method......

    - (NSString *)strCat: (NSString *)one: (NSString *)two
    {
        NSString *myString;
        myString = [NSString stringWithFormat:@"%@%@", one , two];
        return myString;
    }
    

    Then, in whatever function you need it in, set your string or textfield or whatever to the return value of this function.

    Or what you can do to make a shortcut is convert the NSString into a c++ string and use the '+' there.

    Hope this helps!!!!!

    评论
    解决 无用
    打赏 举报
  • csdnceshi62 2012-03-16 00:41

    Well, as colon is kind of special symbol, but is part of method signature, it is possible to exted the NSString with category to add this non-idiomatic style of string concatenation:

    [@"This " : @"feels " : @"almost like " : @"concatenation with operators"];
    

    You can define as many colon separated arguments as you find useful... ;-)

    For a good measure, I've also added concat: with variable arguments that takes nil terminated list of strings.

    //  NSString+Concatenation.h
    
    #import <Foundation/Foundation.h>
    
    @interface NSString (Concatenation)
    
    - (NSString *):(NSString *)a;
    - (NSString *):(NSString *)a :(NSString *)b;
    - (NSString *):(NSString *)a :(NSString *)b :(NSString *)c;
    - (NSString *):(NSString *)a :(NSString *)b :(NSString *)c :(NSString *)d;
    
    - (NSString *)concat:(NSString *)strings, ...;
    
    @end
    
    //  NSString+Concatenation.m
    
    #import "NSString+Concatenation.h"
    
    @implementation NSString (Concatenation)
    
    - (NSString *):(NSString *)a { return [self stringByAppendingString:a];}
    - (NSString *):(NSString *)a :(NSString *)b { return [[self:a]:b];}
    - (NSString *):(NSString *)a :(NSString *)b :(NSString *)c
        { return [[[self:a]:b]:c]; }
    - (NSString *):(NSString *)a :(NSString *)b :(NSString *)c :(NSString *)d
        { return [[[[self:a]:b]:c]:d];}
    
    - (NSString *)concat:(NSString *)strings, ...
    {
        va_list args;
        va_start(args, strings);
    
        NSString *s;    
        NSString *con = [self stringByAppendingString:strings];
    
        while((s = va_arg(args, NSString *))) 
            con = [con stringByAppendingString:s];
    
        va_end(args);
        return con;
    }
    @end
    
    //  NSString+ConcatenationTest.h
    
    #import <SenTestingKit/SenTestingKit.h>
    #import "NSString+Concatenation.h"
    
    @interface NSString_ConcatenationTest : SenTestCase
    
    @end
    
    //  NSString+ConcatenationTest.m
    
    #import "NSString+ConcatenationTest.h"
    
    @implementation NSString_ConcatenationTest
    
    - (void)testSimpleConcatenation 
    {
        STAssertEqualObjects([@"a":@"b"], @"ab", nil);
        STAssertEqualObjects([@"a":@"b":@"c"], @"abc", nil);
        STAssertEqualObjects([@"a":@"b":@"c":@"d"], @"abcd", nil);
        STAssertEqualObjects([@"a":@"b":@"c":@"d":@"e"], @"abcde", nil);
        STAssertEqualObjects([@"this " : @"is " : @"string " : @"concatenation"],
         @"this is string concatenation", nil);
    }
    
    - (void)testVarArgConcatenation 
    {
        NSString *concatenation = [@"a" concat:@"b", nil];
        STAssertEqualObjects(concatenation, @"ab", nil);
    
        concatenation = [concatenation concat:@"c", @"d", concatenation, nil];
        STAssertEqualObjects(concatenation, @"abcdab", nil);
    }
    
    评论
    解决 无用
    打赏 举报
  • 游.程 2012-03-16 14:24

    When building requests for web services, I find doing something like the following is very easy and makes concatenation readable in Xcode:

    NSString* postBody = {
        @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
        @"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
        @" <soap:Body>"
        @"  <WebServiceMethod xmlns=\"\">"
        @"   <parameter>test</parameter>"
        @"  </WebServiceMethod>"
        @" </soap:Body>"
        @"</soap:Envelope>"
    };
    
    评论
    解决 无用
    打赏 举报
  • 程序go 2012-07-03 22:36

    How about shortening stringByAppendingString and use a #define:

    #define and stringByAppendingString
    

    Thus you would use:

    NSString* myString = [@"Hello " and @"world"];
    

    Problem is that it only works for two strings, you're required to wrap additional brackets for more appends:

    NSString* myString = [[@"Hello" and: @" world"] and: @" again"];
    
    评论
    解决 无用
    打赏 举报
  • 零零乙 2012-08-11 06:51

    I keep returning to this post and always end up sorting through the answers to find this simple solution that works with as many variables as needed:

    [NSString stringWithFormat:@"%@/%@/%@", three, two, one];
    

    For example:

    NSString *urlForHttpGet = [NSString stringWithFormat:@"http://example.com/login/username/%@/userid/%i", userName, userId];
    
    评论
    解决 无用
    打赏 举报
  • 10.24 2012-08-30 02:29

    Here's a simple way, using the new array literal syntax:

    NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""];
                      ^^^^^^^ create array ^^^^^
                                                   ^^^^^^^ concatenate ^^^^^
    
    评论
    解决 无用
    打赏 举报
  • 游.程 2012-11-11 18:28

    Try stringWithFormat:

    NSString *myString = [NSString stringWithFormat:@"%@ %@ %@ %d", "The", "Answer", "Is", 42];
    
    评论
    解决 无用
    打赏 举报
  • 程序go 2012-11-14 13:41

    When dealing with strings often I find it easier to make the source file ObjC++, then I can concatenate std::strings using the second method shown in the question.

    std::string stdstr = [nsstr UTF8String];
    
    //easier to read and more portable string manipulation goes here...
    
    NSString* nsstr = [NSString stringWithUTF8String:stdstr.c_str()];
    
    评论
    解决 无用
    打赏 举报
  • 笑故挽风 2013-01-22 04:10
    listOfCatalogIDs =[@[@"id[]=",listOfCatalogIDs] componentsJoinedByString:@""];
    
    评论
    解决 无用
    打赏 举报
  • 撒拉嘿哟木头 2013-04-05 05:38

    You can use NSArray as

    NSString *string1=@"This"
    
    NSString *string2=@"is just"
    
    NSString *string3=@"a test"  
    
    NSArray *myStrings = [[NSArray alloc] initWithObjects:string1, string2, string3,nil];
    
    NSString *fullLengthString = [myStrings componentsJoinedByString:@" "];
    

    or

    you can use

    NSString *imageFullName=[NSString stringWithFormat:@"%@ %@ %@.", string1,string2,string3];
    
    评论
    解决 无用
    打赏 举报
  • ~Onlooker 2013-04-29 07:35
    NSString *result=[NSString stringWithFormat:@"%@ %@", @"Hello", @"World"];
    
    评论
    解决 无用
    打赏 举报
  • 喵-见缝插针 2013-05-11 16:38

    I tried this code. it's worked for me.

    NSMutableString * myString=[[NSMutableString alloc]init];
    myString=[myString stringByAppendingString:@"first value"];
    myString=[myString stringByAppendingString:@"second string"];
    
    评论
    解决 无用
    打赏 举报
  • Macro:

    // stringConcat(...)
    //     A shortcut for concatenating strings (or objects' string representations).
    //     Input: Any number of non-nil NSObjects.
    //     Output: All arguments concatenated together into a single NSString.
    
    #define stringConcat(...) \
        [@[__VA_ARGS__] componentsJoinedByString:@""]
    

    Test Cases:

    - (void)testStringConcat {
        NSString *actual;
    
        actual = stringConcat(); //might not make sense, but it's still a valid expression.
        STAssertEqualObjects(@"", actual, @"stringConcat");
    
        actual = stringConcat(@"A");
        STAssertEqualObjects(@"A", actual, @"stringConcat");
    
        actual = stringConcat(@"A", @"B");
        STAssertEqualObjects(@"AB", actual, @"stringConcat");
    
        actual = stringConcat(@"A", @"B", @"C");
        STAssertEqualObjects(@"ABC", actual, @"stringConcat");
    
        // works on all NSObjects (not just strings):
        actual = stringConcat(@1, @" ", @2, @" ", @3);
        STAssertEqualObjects(@"1 2 3", actual, @"stringConcat");
    }
    

    Alternate macro: (if you wanted to enforce a minimum number of arguments)

    // stringConcat(...)
    //     A shortcut for concatenating strings (or objects' string representations).
    //     Input: Two or more non-nil NSObjects.
    //     Output: All arguments concatenated together into a single NSString.
    
    #define stringConcat(str1, str2, ...) \
        [@[ str1, str2, ##__VA_ARGS__] componentsJoinedByString:@""];
    
    评论
    解决 无用
    打赏 举报
  • local-host 2013-08-01 13:13
    NSString *myString = @"This";
    NSString *test = [myString stringByAppendingString:@" is just a test"];
    

    After a couple of years now with Objective C I think this is the best way to work with Objective C to achieve what you are trying to achieve.

    Start keying in "N" in your Xcode application and it autocompletes to "NSString". key in "str" and it autocompletes to "stringByAppendingString". So the keystrokes are quite limited.

    Once you get the hang of hitting the "@" key and tabbing the process of writing readable code no longer becomes a problem. It is just a matter of adapting.

    评论
    解决 无用
    打赏 举报
  • elliott.david 2014-04-07 11:45

    Was trying the following in the lldb pane

    [NSString stringWithFormat:@"%@/%@/%@", three, two, one];
    

    which errors.

    instead use alloc and initWithFormat method:

    [[NSString alloc] initWithFormat:@"%@/%@/%@", @"three", @"two", @"one"];
    
    评论
    解决 无用
    打赏 举报
  • ℙℕℤℝ 2016-01-20 13:42
    NSNumber *lat = [NSNumber numberWithDouble:destinationMapView.camera.target.latitude];
    NSNumber *lon = [NSNumber numberWithDouble:destinationMapView.camera.target.longitude];
    NSString *DesconCatenated = [NSString stringWithFormat:@"%@|%@",lat,lon];
    
    评论
    解决 无用
    打赏 举报
  • 喵-见缝插针 2016-01-28 20:36

    Either of these formats work in XCode7 when I tested:

    NSString *sTest1 = {@"This" " and that" " and one more"};
    NSString *sTest2 = {
      @"This"
      " and that"
      " and one more"
    };
    
    NSLog(@"\n%@\n\n%@",sTest1,sTest2);
    

    For some reason, you only need the @ operator character on the first string of the mix.

    However, it doesn't work with variable insertion. For that, you can use this extremely simple solution with the exception of using a macro on "cat" instead of "and".

    评论
    解决 无用
    打赏 举报
  • local-host 2016-03-03 08:42

    In Swift

    let str1 = "This"
    let str2 = "is just a test"
    
    var appendStr1 = "\(str1) \(str2)" // appendStr1 would be "This is just a test"
    var appendStr2 = str1 + str2 // // appendStr2 would be "This is just a test"
    

    Also, you can use += operator for the same as below...

    var str3 = "Some String" 
    str3 += str2            // str3 would be "Some String is just a test"
    
    评论
    解决 无用
    打赏 举报
  • ℙℕℤℝ 2016-05-27 08:08

    Let's imagine that u don't know how many strings there.

    NSMutableArray *arrForStrings = [[NSMutableArray alloc] init];
    for (int i=0; i<[allMyStrings count]; i++) {
        NSString *str = [allMyStrings objectAtIndex:i];
        [arrForStrings addObject:str];
    }
    NSString *readyString = [[arrForStrings mutableCopy] componentsJoinedByString:@", "];
    
    评论
    解决 无用
    打赏 举报
  • 斗士狗 2016-06-07 08:45

    For all Objective C lovers that need this in a UI-Test:

    -(void) clearTextField:(XCUIElement*) textField{
    
        NSString* currentInput = (NSString*) textField.value;
        NSMutableString* deleteString = [NSMutableString new];
    
        for(int i = 0; i < currentInput.length; ++i) {
            [deleteString appendString: [NSString stringWithFormat:@"%c", 8]];
        }
        [textField typeText:deleteString];
    }
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题