Objective-C中的快捷方式用于连接NSStrings

typ*_*ror 1114 objective-c string-concatenation nsstring

stringByAppendingString:Objective-C中是否存在()字符串连接的快捷方式,或者NSString通常使用的快捷方式?

例如,我想做:

NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];
Run Code Online (Sandbox Code Playgroud)

更像是:

string myString = "This";
string test = myString + " is just a test";
Run Code Online (Sandbox Code Playgroud)

dic*_*ciu 1117

一个选项:

[NSString stringWithFormat:@"%@/%@/%@", one, two, three];
Run Code Online (Sandbox Code Playgroud)

另外一个选项:

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

NSLog(@"%@", [Util append:one, @" ", two, nil]); // "one two"
NSLog(@"%@", [Util append:three, @"/", two, @"/", one, nil]); // three/two/one
Run Code Online (Sandbox Code Playgroud)

使用类似的东西

+ (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;
}
Run Code Online (Sandbox Code Playgroud)

  • @pablasso同意.Util方法非常难看.如果你想要这样的东西,它应该作为NSString类别完成,其名称类似于+ stringByAppendingStrings:.即使是像NSStringForAppendedStrings(...)这样的名字的直接函数也会比像Util这样的类中的静态方法更好(名称中带有"Util"的东西可能很少考虑因素).使用NSMutableString和-appendString也可以更好地实现该函数,以避免创建一组无限制的临时自动释放NSStrings. (8认同)
  • stringWithFormat 不仅非常优雅,而且功能更强大。您可以将其与 @"%@%@" 一起使用来连接两个字符串,使用 @"%@%@%@" 来连接三个字符串,但您可以在其中放入任何额外的字符、打印数字、重新排序参数(如果您愿意)等等。格式字符串可以本地化,使其功能强大十倍。字符串连接适合初学者。 (2认同)

Chr*_*ell 609

我能想到的两个答案......既不像只有一个连接运算符那么特别令人愉快.

首先,使用a NSMutableString,它有一个appendString方法,消除了对额外临时字符串的一些需求.

其次,使用an NSArray通过componentsJoinedByString方法连接.

  • 虽然另一个选项有许多赞成票,但我认为如果您在构建时不知道所有字符串,这是最好的答案.每次附加一个字符串时,都会产生很多开销.使用可变字符串可以消除该问题. (34认同)
  • `[NSString stringWithFormat:@"%@ /%@ /%@",三,二,一];`技术似乎最优雅.它应该是选定的答案. (27认同)
  • +1同意w @Eli.这些通常是最好的解决方案.NSArray -componentsJoinedByString可以很好地在一行中完成:string = [[NSArray arrayWithObjects:@"This","Is","A","Test",nil] componentsJoinedByString:@""]; (22认同)
  • 这个答案+1.`[NSMutableString appendString]`比`[NSString stringByAppendingStrings]`更加内存友好. (4认同)
  • @RobNapier:现在使用新的数组文字语法,它甚至更好. (2认同)

Joh*_*rug 148

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

NSString *joinedFromLiterals = @"ONE " @"MILLION " @"YEARS " @"DUNGEON!!!";
Run Code Online (Sandbox Code Playgroud)

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

#define STRINGA @"Also, I don't know "
#define STRINGB @"where food comes from."
#define JOINED STRINGA STRINGB
Run Code Online (Sandbox Code Playgroud)

请享用.

  • @CristiBăluţă:)但这只适用于_literals_而不适用于动态创建的NSString实例. (13认同)
  • 你实际上在第一个之后不需要字符串上的`@`s.`@"我""真的""享受"...` (9认同)

Kyl*_*egg 72

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

[NSString stringWithFormat:@"%@/%@/%@", three, two, one];
Run Code Online (Sandbox Code Playgroud)

例如:

NSString *urlForHttpGet = [NSString stringWithFormat:@"http://example.com/login/username/%@/userid/%i", userName, userId];
Run Code Online (Sandbox Code Playgroud)


Sid*_*non 45

创建方法:

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

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

或者,要创建快捷方式,请将NSString转换为C++字符串并在其中使用"+".


Pal*_*ndo 44

好吧,冒号是一种特殊符号,但是方法签名的一部分,可以NSString通过类别来添加这种非惯用的字符串连接样式:

[@"This " : @"feels " : @"almost like " : @"concatenation with operators"];
Run Code Online (Sandbox Code Playgroud)

你可以定义尽可能多的冒号分隔的参数...... ;-)

为了更好的衡量,我还添加了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);
}
Run Code Online (Sandbox Code Playgroud)

  • 我在一年前对此进行了投票,因为这不是一个很好的答案.为了应对连接大量字符串,Palimondo的实现需要实现大量非常相似的查找方法,或者多次调用方法,从而导致大量代码基本上只是连接字符串.使用这种方法,你没有比简单的`stringWithFormat:`获得任何好处.更不用说缺少命名参数,这不仅是非标准的,而且是令人困惑的. (20认同)
  • 最初的提问者提到了`stringByAppendingString`,他从未说过使用两个以上的参数.我比这个答案更喜欢这个答案.这很聪明. (2认同)

Tai*_*mal 31

使用这种方式:

NSString *string1, *string2, *result;

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

result = [result stringByAppendingString:string1];
result = [result stringByAppendingString:string2];
Run Code Online (Sandbox Code Playgroud)

要么

result = [result stringByAppendingString:@"This is "];
result = [result stringByAppendingString:@"my string."];
Run Code Online (Sandbox Code Playgroud)

  • 你确实意识到你在暗示他想要的确切事情*不是*做的,对吧? (33认同)

Eth*_*anB 29

宏:

// 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:@""]
Run Code Online (Sandbox Code Playgroud)

测试用例:

- (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");
}
Run Code Online (Sandbox Code Playgroud)

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

// 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:@""];
Run Code Online (Sandbox Code Playgroud)

  • 有一段时间没有检查过这个问题,但是这些年后我倾向于接受这个作为正确的答案! (2认同)

Fre*_*eer 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>"
};
Run Code Online (Sandbox Code Playgroud)

  • @NormanH:这实际上是C语言的一部分.经过一番挖掘,我找到了[这个](http://msdn.microsoft.com/en-us/library/bxss3ska(v = vs.80).aspx).它在"字符串连接"阶段下声明:所有相邻的字符串和宽字符串文字是连接在一起的.例如,"String""concatenation"变为"String concatenation". (2认同)

小智 24

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

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

注意:

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

  • 这些宏的问题在于它们破坏了Objective-C的一个主要目标,即可读性.目前还不清楚"AS"的作用.以可读性为代价保存一些键击(其中大多数是使用自动完成处理)很少是一个很好的权衡.有一些例外(@""语法比每次使用+ stringWithUTF8String更具可读性,但目标应该仍然是可读性,而不仅仅是简洁性.你写了一次,但你永远调试. (15认同)
  • 或者,只需缩短像"#define AS stringByAppendingString"这样的宏所需的输入,然后只需使用"AS",您通常会键入"stringByAppendingString",并享受每行代码的多个附加. (2认同)

cod*_*284 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];
Run Code Online (Sandbox Code Playgroud)


jus*_*tin 10

这是一种简单的方法,使用新的数组文字语法:

NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""];
                  ^^^^^^^ create array ^^^^^
                                               ^^^^^^^ concatenate ^^^^^
Run Code Online (Sandbox Code Playgroud)


Ian*_*lay 9

NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];
Run Code Online (Sandbox Code Playgroud)

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

在Xcode应用程序中开始键入"N",它自动完成"NSString".键入"str"并自动填充"stringByAppendingString".因此击键非常有限.

一旦你掌握了点击"@"键并且标记编写可读代码的过程不再成为问题.这只是一个适应的问题.


小智 8

c = [a stringByAppendingString: b]缩短的唯一方法是在该st点附近使用自动完成功能.该+运营商是C,不知道Objective-C对象的一部分.


Sun*_*oot 8

如何缩短stringByAppendingString和使用#define:

#define and stringByAppendingString
Run Code Online (Sandbox Code Playgroud)

因此你会使用:

NSString* myString = [@"Hello " and @"world"];
Run Code Online (Sandbox Code Playgroud)

问题是它只适用于两个字符串,你需要包含额外的括号以获得更多的附加内容:

NSString* myString = [[@"Hello" and: @" world"] and: @" again"];
Run Code Online (Sandbox Code Playgroud)


Gob*_*i M 8

NSString *result=[NSString stringWithFormat:@"%@ %@", @"Hello", @"World"];
Run Code Online (Sandbox Code Playgroud)


小智 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];
Run Code Online (Sandbox Code Playgroud)


Erh*_*rci 6

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

NSMutableString * myString=[[NSMutableString alloc]init];
myString=[myString stringByAppendingString:@"first value"];
myString=[myString stringByAppendingString:@"second string"];
Run Code Online (Sandbox Code Playgroud)

  • 这是 NSMutableString 有史以来最严重的滥用。NSMutableString 的全部意义在于您不需要创建自动释放字符串的方法,但可以修改字符串本身。 (2认同)

Ant*_*uza 6

lldb窗格中尝试以下内容

[NSString stringWithFormat:@"%@/%@/%@", three, two, one];
Run Code Online (Sandbox Code Playgroud)

哪个错误.

而是使用alloc和initWithFormat方法:

[[NSString alloc] initWithFormat:@"%@/%@/%@", @"three", @"two", @"one"];
Run Code Online (Sandbox Code Playgroud)