1159

在 Objective-C 中是否有 ( stringByAppendingString:) 字符串连接的快捷方式,或NSString一般使用的快捷方式?

例如,我想做:

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

更像是:

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

30 回答 30

1163

一个选项:

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

另外一个选项:

我猜你对多个附加 (a+b+c+d) 不满意,在这种情况下你可以这样做:

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

使用类似的东西

+ (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;
}
于 2009-02-04T07:53:32.213 回答
631

我能想到的两个答案......都没有一个连接运算符那么特别令人愉快。

首先,使用NSMutableString具有appendString方法的 ,消除对额外临时字符串的一些需求。

其次,使用 anNSArray通过componentsJoinedByString方法连接。

于 2009-02-04T06:44:42.353 回答
156

如果你有 2 个 NSString文字,你也可以这样做:

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

这对于加入#defines 也很有用:

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

享受。

于 2011-03-17T11:59:13.837 回答
82

我不断返回这篇文章,并总是最终对答案进行排序,以找到这个简单的解决方案,它可以根据需要使用尽可能多的变量:

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

例如:

NSString *urlForHttpGet = [NSString stringWithFormat:@"http://example.com/login/username/%@/userid/%i", userName, userId];
于 2012-08-11T06:51:02.400 回答
53

创建一个方法:

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

然后,在您需要它的任何函数中,将您的字符串或文本字段或其他任何内容设置为此函数的返回值。

或者,要创建一个快捷方式,将 NSString 转换为 C++ 字符串并在此处使用“+”。

于 2011-10-03T22:29:02.840 回答
45

好吧,由于冒号是一种特殊符号,但它方法签名的一部分,因此可以扩展NSStringwith 类别以添加这种非惯用的字符串连接样式:

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

您可以定义尽可能多的冒号分隔的参数,只要您觉得有用... ;-)

作为一个很好的衡量标准,我还添加concat:了可变参数,这些参数采用nil终止的字符串列表。

//  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-16T00:41:54.720 回答
37

使用stringByAppendingString:这种方式:

NSString *string1, *string2, *result;

string1 = @"This is ";
string2 = @"my string.";

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

或者

result = [result stringByAppendingString:@"This is "];
result = [result stringByAppendingString:@"my string."];
于 2010-07-26T16:04:03.143 回答
31

宏:

// 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:@""]

测试用例:

- (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");
}

备用宏:(如果您想强制执行最少数量的参数)

// 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:@""];
于 2013-05-31T17:07:51.677 回答
27

通过创建 AppendString (AS) 宏的快捷方式...

#define AS(A,B) [(A) stringByAppendingString:(B)]
NSString *myString = @"这个"; NSString *test = AS(myString,@" 只是一个测试");

笔记:

如果使用宏,当然只需使用可变参数即可,请参阅 EthanB 的答案。

于 2009-07-18T05:38:30.367 回答
27

在构建 Web 服务请求时,我发现执行以下操作非常容易,并且可以在 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>"
};
于 2012-03-16T14:24:43.240 回答
13
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];
于 2010-06-10T09:50:33.863 回答
11

这是一个简单的方法,使用新的数组字面量语法:

NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""];
                  ^^^^^^^ create array ^^^^^
                                               ^^^^^^^ concatenate ^^^^^
于 2012-08-30T02:29:57.343 回答
9
NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];

在使用 Objective CI 几年后,认为这是使用 Objective C 实现您想要实现的目标的最佳方式。

在您的 Xcode 应用程序中开始键入“N”,它会自动完成为“NSString”。键入“str”,它会自动完成“stringByAppendingString”。所以击键是相当有限的。

一旦你掌握了按“@”键和制表符的窍门,编写可读代码的过程就不再是问题了。这只是适应的问题。

于 2013-08-01T13:13:10.803 回答
8

缩短时间的唯一方法c = [a stringByAppendingString: b]是在该st点附近使用自动完成功能。运算符是 C的+一部分,它不了解 Objective-C 对象。

于 2009-02-04T07:25:32.113 回答
8

如何缩短stringByAppendingString并使用#define

#define and stringByAppendingString

因此,您将使用:

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

问题是它仅适用于两个字符串,您需要包装额外的括号以进行更多附加:

NSString* myString = [[@"Hello" and: @" world"] and: @" again"];
于 2012-07-03T22:36:29.943 回答
8
NSString *result=[NSString stringWithFormat:@"%@ %@", @"Hello", @"World"];
于 2013-04-29T07:35:26.753 回答
7
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];
于 2009-06-20T17:38:10.623 回答
6

我试过这段代码。它对我有用。

NSMutableString * myString=[[NSMutableString alloc]init];
myString=[myString stringByAppendingString:@"first value"];
myString=[myString stringByAppendingString:@"second string"];
于 2013-05-11T16:38:10.857 回答
6

lldb在窗格中尝试以下操作

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

哪些错误。

而是使用 alloc 和initWithFormat方法:

[[NSString alloc] initWithFormat:@"%@/%@/%@", @"three", @"two", @"one"];
于 2014-04-07T11:45:00.340 回答
4

这是为了更好的记录,并且只记录 - 基于 dicius 优秀的多参数方法。我定义了一个 Logger 类,并像这样调用它:

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

几乎很好,除了必须用“nil”结束var args,但我想在Objective-C中没有办法解决这个问题。

记录器.h

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

记录器.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 

为了只连接字符串,我将在 NSString 上定义一个 Category 并向其添加一个静态 (+) 连接方法,该方法看起来与上面的 log 方法完全相同,只是它返回字符串。它在 NSString 上,因为它是一个字符串方法,它是静态的,因为您想从 1-N 个字符串创建一个新字符串,而不是在作为附加部分的任何一个字符串上调用它。

于 2011-03-23T17:37:16.933 回答
4
NSNumber *lat = [NSNumber numberWithDouble:destinationMapView.camera.target.latitude];
NSNumber *lon = [NSNumber numberWithDouble:destinationMapView.camera.target.longitude];
NSString *DesconCatenated = [NSString stringWithFormat:@"%@|%@",lat,lon];
于 2016-01-20T13:42:08.703 回答
3

试试 stringWithFormat:

NSString *myString = [NSString stringWithFormat:@"%@ %@ %@ %d", "The", "Answer", "Is", 42];
于 2012-11-11T18:28:04.673 回答
3

经常处理字符串时,我发现制作源文件 ObjC++ 更容易,然后我可以使用问题中显示的第二种方法连接 std::strings 。

std::string stdstr = [nsstr UTF8String];

//easier to read and more portable string manipulation goes here...

NSString* nsstr = [NSString stringWithUTF8String:stdstr.c_str()];
于 2012-11-14T13:41:42.067 回答
3

您可以使用 NSArray 作为

NSString *string1=@"This"

NSString *string2=@"is just"

NSString *string3=@"a test"  

NSArray *myStrings = [[NSArray alloc] initWithObjects:string1, string2, string3,nil];

NSString *fullLengthString = [myStrings componentsJoinedByString:@" "];

或者

您可以使用

NSString *imageFullName=[NSString stringWithFormat:@"%@ %@ %@.", string1,string2,string3];
于 2013-04-05T05:38:00.580 回答
3

我的首选方法是这样的:

NSString *firstString = @"foo";
NSString *secondString = @"bar";
NSString *thirdString = @"baz";

NSString *joinedString = [@[firstString, secondString, thirdString] join];

您可以通过将 join 方法添加到具有类别的 NSArray 来实现:

#import "NSArray+Join.h"
@implementation NSArray (Join)
-(NSString *)join
{
    return [self componentsJoinedByString:@""];
}
@end

@[]这是 的简短定义NSArray,我认为这是连接字符串的最快方法。

如果不想使用类别,直接使用componentsJoinedByString:方法:

NSString *joinedString = [@[firstString, secondString, thirdString] componentsJoinedByString:@""];
于 2013-05-03T16:40:46.693 回答
1

当我测试时,这些格式中的任何一种都可以在 XCode7 中使用:

NSString *sTest1 = {@"This" " and that" " and one more"};
NSString *sTest2 = {
  @"This"
  " and that"
  " and one more"
};

NSLog(@"\n%@\n\n%@",sTest1,sTest2);

出于某种原因,您只需要在组合的第一个字符串上使用 @ 运算符字符。

但是,它不适用于变量插入。为此,您可以使用这个极其简单的解决方案,除了在“cat”上使用宏而不是“and”。

于 2016-01-28T20:36:03.760 回答
1

对于所有在 UI 测试中需要此功能的 Objective C 爱好者:

-(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];
}
于 2016-06-07T08:45:00.043 回答
0
listOfCatalogIDs =[@[@"id[]=",listOfCatalogIDs] componentsJoinedByString:@""];
于 2013-01-22T04:10:27.317 回答
0

让我们想象一下,你不知道那里有多少个字符串。

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-05-27T08:08:35.937 回答
0

NSMutableString克里斯的想法启发,我做了一个完美的宏恕我直言。它支持插入 nil 元素而没有任何异常。

#import <libextobjc/metamacros.h>

#define STR_CONCAT(...) \
    ({ \
        __auto_type str__ = [NSMutableString string]; \
        metamacro_foreach_cxt(never_use_immediately_str_concatify_,, str__, __VA_ARGS__) \
        (NSString *)str__.copy; \
    })

#define never_use_immediately_str_concatify_(INDEX, CONTEXT, VAR) \
    [CONTEXT appendString:VAR ?: @""];

例子:

STR_CONCAT(@"button_bg_", @(count).stringValue, @".png"); 
// button_bg_2.png

如果你喜欢,你可以使用idtype 作为参数,[VAR description]而不是NSString.

于 2020-10-27T06:26:51.757 回答