ทางลัดใน Objective-C เพื่อต่อ NSStrings


1129

มีทางลัดไปยัง ( stringByAppendingString:) การต่อสตริงใน Objective-C หรือทางลัดสำหรับการทำงานNSStringโดยทั่วไปหรือไม่?

ตัวอย่างเช่นฉันต้องการทำ:

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

บางสิ่งที่ชอบมากขึ้น:

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

4
ฉันแค่ต้องการเสนอ '@ +' เป็นตัวดำเนินการเรียงต่อกัน ฉันจะคาดหวังสิ่งนี้ในการปรับปรุงครั้งต่อไปสำหรับ Objective-C, kthxbai
powerj1984

44
@NicolasMiari นี่ไม่ใช่คุณสมบัติเดียวที่ Objective-C ขาด มีคนอื่นอีกหลายสิบคน การอ้างอิงจากลิงก์ Jordãoที่โพสต์: "Objective-C คือภาษาทื่อซึ่งเป็นภาษาดั้งเดิมเปรียบเทียบกับภาษาสมัยใหม่และคุณจะพบว่ามันขาด" ฉันเห็นด้วย. วัตถุประสงค์ -C (ต้นทศวรรษ 1980) คือ C (ต้นปี 1970) ด้วยการเพิ่ม OOP ชนิดที่เรียบง่ายและไม่ปลอดภัยมาก ไม่เป็นไร แต่เมื่อเทียบกับ Java หรือ C # มันให้ความรู้สึกที่ล้าสมัยมาก
jcsahnwaldt พูดว่า GoFundMonica

5
@NicolasMiari: ภาษาแปลความหมาย? C # และ Java เป็นภาษาที่รวบรวม เรียบเรียงเป็น bytecode ซึ่งจะถูกคอมไพล์อีกครั้งกับรหัสเครื่อง
Joren

3
ตอนนี้สิ่งต่าง ๆ กำลังเปลี่ยนแปลงอย่างรวดเร็ว (ภาษาใหม่ของแอปเปิ้ล) ตรงไปตรงมามากขึ้น
Pradeep

6
เกี่ยวกับ "ความปลอดภัยของประเภท" ฉันคิดว่ามันเป็นปัญหาของสไตล์ สำหรับคนที่มาจาก C # / C ++ การมีอาร์เรย์ที่แตกต่างกันของวัตถุประเภทใด ๆ อาจดูแปลก แต่สำหรับคนที่คุ้นเคยกับ Objective-C / Cocoa มันเป็นรูปแบบของการเคลื่อนไหวและเสรีภาพ มันเป็นข้อได้เปรียบหากคุณรู้ว่าคุณกำลังทำอะไร ชอบทุกอย่างสวยมากเกี่ยวกับ C ที่โปรแกรมเมอร์น้องทุบตีวันนี้ ...
นิโคลัส Miari

คำตอบ:


616

คำตอบสองข้อที่ฉันสามารถนึกได้ ... ทั้งสองอย่างนั้นไม่น่าพอใจเท่ากับการมีผู้ดำเนินการเรียงต่อกัน

ก่อนอื่นใช้อันNSMutableStringที่มีappendStringเมธอดโดยลบความต้องการบางอย่างของสตริง temp พิเศษออก

ประการที่สองใช้NSArrayเพื่อเชื่อมต่อผ่านcomponentsJoinedByStringวิธีการ


34
แม้ว่าตัวเลือกอื่นมี upvotes มากมายฉันคิดว่านี่เป็นคำตอบที่ดีที่สุดหากคุณไม่รู้จักสตริงทั้งหมดของคุณในระหว่างการก่อสร้าง ทุกครั้งที่คุณต่อท้ายสตริงคุณกำลังสร้างค่าใช้จ่ายจำนวนมาก การใช้สตริงที่เปลี่ยนแปลงได้จะลบปัญหานั้นออก
อีไล

22
+1 เห็นด้วย w @Eli โดยทั่วไปนี่เป็นทางออกที่ดีที่สุด NSArray - ส่วนประกอบ JoinedByString สามารถทำได้ในบรรทัดเดียวค่อนข้างดี: string = [[NSArray arrayWithObjects: @ "นี่", "Is", "A", "Test", nil] componentsJoinedByString: @ ""];
Rob Napier

4
+1 สำหรับคำตอบนี้ เป็นหน่วยความจำมากขึ้นกว่าที่เป็นมิตร[NSMutableString appendString] [NSString stringByAppendingStrings]
Pierre-David Belanger

2
@RobNapier: ตอนนี้ด้วยไวยากรณ์ตัวอักษรอาร์เรย์ใหม่มันจะดียิ่งขึ้น
Amogh Talpallikar

27
[NSString stringWithFormat:@"%@/%@/%@", three, two, one];เทคนิคดูเหมือนว่าที่หรูหราที่สุด ควรเป็นคำตอบที่เลือก
ekillaby

1129

ตัวเลือก:

[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;
}

8
@pablasso เห็นด้วย วิธีการใช้ประโยชน์ค่อนข้างน่าเกลียด หากคุณต้องการสิ่งนั้นควรทำเป็นหมวดหมู่ NSString ที่มีชื่อเช่น + stringByAppendingStrings: แม้แต่ฟังก์ชั่นตรงที่มีชื่ออย่าง NSStringForAppendedStrings (... ) จะดีกว่าวิธีการคงที่ในคลาสอย่าง Util (ทุกอย่างที่มี "Util" ในชื่อนั้นน่าจะเป็นปัจจัยที่ไม่ดี) ฟังก์ชั่นนี้ยังใช้งานได้ดีขึ้นด้วย NSMutableString และ -appendString เพื่อหลีกเลี่ยงการสร้างชุด NSStrings อัตโนมัติที่ไม่มีขีด จำกัด
Rob Napier

1
ด้วยสตริงจำนวนมากสิ่งนี้อาจทำให้หน่วยความจำเสีย แนะนำเป็นสิ่งเพิ่มเติมเช่น StringBuilder ในภาษาการเขียนโปรแกรมจริง จากนั้นคุณสามารถหาจำนวนหน่วยความจำที่ต้องการก่อนที่จะเริ่มต่อท้าย วิธีการข้างต้นสามารถ refactored ทำเช่นนี้ อย่างไรก็ตามจะเป็นการดีกว่าถ้าจะสร้างออบเจ็กต์ StringBuilder เนื่องจากจะช่วยให้ผู้ใช้ไม่ต้องติดตามรายการของสตริงทั้งหมดที่พวกเขาต้องการรวมกัน
George

คุณจะนำเข้า Util ได้อย่างไร IDE นี้น่าผิดหวัง (ไม่แนะ "นำเข้า something.Util" เช่นเดียวกับคราสและฉันพบการกล่าวถึง "Util" ทุกที่ไม่มีนี่คือระดับที่ฉันควรจะรหัสตัวเอง.
Gubatron

stringWithFormat ไม่เพียง แต่สง่างามเท่านั้น แต่ยังทรงพลังกว่าด้วย คุณใช้กับ @ "% @% @" เพื่อเชื่อมสองสายเข้าด้วยกัน, @ "% @% @% @" เพื่อเชื่อมสามสายเข้าด้วยกัน แต่คุณสามารถใส่อักขระพิเศษใด ๆ ข้างใน, พิมพ์หมายเลข, จัดลำดับพารามิเตอร์ใหม่ได้ตามต้องการ . สตริงรูปแบบสามารถแปลเป็นภาษาท้องถิ่นทำให้มีประสิทธิภาพยิ่งขึ้นสิบเท่า การต่อข้อมูลสตริงสำหรับผู้เริ่มต้น
gnasher729

150

หากคุณมีตัวอักษร NSString 2 ตัวคุณสามารถทำสิ่งนี้ได้:

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

นั่นเป็นประโยชน์สำหรับการเข้าร่วม #defines:

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

สนุก.


13
@ CristiBăluță :) แต่วิธีนี้ใช้ได้เฉพาะกับตัวอักษรไม่ใช่กับอินสแตนซ์ NSString ที่สร้างขึ้นแบบไดนามิก
Johannes Fahrenkrug

9
คุณไม่จำเป็นต้อง@ใช้สตริงหลังจากที่แรก @"I" " really" " enjoy"...
เควิน

คุณอาจต้องการวาง STRINGA และ STRINGB ไว้ในวงเล็บมิฉะนั้นคุณอาจได้รับผลลัพธ์แปลก ๆ เมื่อแก้ไขแมโคร #define เข้าร่วม (STRINGA STRINGB)
digory doo

@JohannesFahrenkrug ถ้าอย่างนั้นทำไมมันNSString* const SQL_CREATE_TABLE_str = @"CREATE TABLE IF NOT EXISTS " TABLE_NAME @" (...);";ใช้งานไม่ได้? ฉันมีExpected '@' in programข้อผิดพลาด :(
Vagif

@Vagif มีการTABLE_NAMEกำหนดอย่างไร?
Johannes Fahrenkrug

75

ฉันกลับไปที่โพสต์นี้และเรียงลำดับคำตอบเสมอเพื่อหาวิธีแก้ปัญหาง่ายๆที่ทำงานกับตัวแปรได้มากเท่าที่ต้องการ:

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

ตัวอย่างเช่น:

NSString *urlForHttpGet = [NSString stringWithFormat:@"http://example.com/login/username/%@/userid/%i", userName, userId];

48

สร้างวิธีการ:

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

จากนั้นในฟังก์ชันใดก็ตามที่คุณต้องการให้ตั้งค่าสตริงหรือฟิลด์ข้อความของคุณหรืออะไรก็ตามที่ส่งคืนค่าของฟังก์ชันนี้

หรือหากต้องการสร้างทางลัดให้แปลง NSString เป็นสตริง C ++ และใช้ '+' ที่นั่น


นี่เป็นทางออกที่ง่ายที่สุด
GeneCode

44

ในขณะที่เครื่องหมายจุดคู่เป็นสัญลักษณ์พิเศษชนิดหนึ่ง แต่เป็นส่วนหนึ่งของการลงนามเมธอดจึงเป็นไปได้ที่จะขยายNSStringประเภทด้วยเพื่อเพิ่มสไตล์การเรียงสตริงที่ไม่ใช้สำนวนนี้:

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

20
ฉันลงคะแนนเมื่อปีที่แล้วเพราะมันไม่ใช่คำตอบที่ดีมาก เพื่อจัดการกับการเรียงสตริงจำนวนมากการใช้ Palimondo นั้นจำเป็นต้องใช้วิธีการค้นหาที่คล้ายกันจำนวนมากหรือการเรียกใช้เมธอดหลายครั้งทำให้เกิดโค้ดขนาดใหญ่ที่เชื่อมโยงสตริง ใช้วิธีนี้คุณจะไม่ได้รับประโยชน์ใด ๆ stringWithFormat:ในช่วงที่เรียบง่าย ไม่พูดถึงการขาดพารามิเตอร์ที่มีชื่อซึ่งไม่เพียง แต่ไม่ได้มาตรฐาน แต่ยังทำให้เกิดความสับสน
FreeAsInBeer

2
ผู้stringByAppendingStringถามดั้งเดิมพูดถึงและเขาไม่เคยพูดอะไรเกี่ยวกับการใช้อาร์กิวเมนต์มากกว่าสองข้อ ฉันชอบคำตอบนี้ดีกว่าคำตอบที่ยอมรับ มันค่อนข้างฉลาด
sudo

32

ใช้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."];

34
คุณรู้ว่าคุณกำลังแนะนำสิ่งที่แน่นอนที่เขาไม่ต้องการทำใช่ไหม?
SilverSideDown

การรั่วไหลมาก!
RamGrg

30

มาโคร

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

2
ยังไม่ได้ตรวจสอบคำถามนี้ในขณะที่ แต่ฉันพิงยอมรับว่านี่เป็นคำตอบที่ถูกต้องหลังจากปีที่ผ่านมา!
typeoneerror

1
สิ่งนี้ยังมีพฤติกรรมที่ดีกว่า-[NSString stringByAppendingString:]สำหรับกรณีการใช้งานนี้ด้วยในอดีตคุณจะได้รับการยกเว้นถ้าการโต้แย้งนั้นเกิดขึ้นnilแต่ไม่ใช่หากผู้รับเป็น ดังนั้นจึงเป็นไปได้ 50% ที่ความผิดพลาดในเครื่องป้อนสตริงของคุณจะล้มเหลวอย่างเงียบ ๆ และ 50% สำหรับข้อยกเว้น ด้วยstringConcatการรับประกันว่าคุณจะได้รับการยกเว้นในทุก ๆnilที่ในรายการ ซึ่งอย่างน้อยก็คาดเดาได้มากกว่า
Tommy

27

เมื่อสร้างคำขอสำหรับบริการบนเว็บฉันพบว่าการทำสิ่งต่อไปนี้นั้นง่ายมากและทำให้การต่อข้อมูลใน 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>"
};

สำหรับ noob วัตถุประสงค์ -c คุณสามารถอธิบายสิ่งที่ไวยากรณ์นี้จะทำอย่างไร นี่เป็นการสร้างชุดของสตริงและเข้าร่วมกับพวกเขาอย่างไร การอ้างอิงถึงเอกสารใด ๆ ก็จะยอดเยี่ยมเช่นกัน
Norman H

2
@NormanH: นี่เป็นส่วนหนึ่งของภาษา C หลังจากขุดเล็กน้อยฉันก็พบสิ่งนี้ได้ มันระบุไว้ภายใต้เฟส "การต่อสตริง": สตริงที่อยู่ติดกันทั้งหมดและตัวอักษรสตริงกว้างจะถูกต่อกัน ตัวอย่างเช่น "String" "concatenation" กลายเป็น "String concatenation"
FreeAsInBeer

27

ทางลัดด้วยการสร้างมาโคร AppendString (AS) ...

#define AS (A, B) [(A) stringByAppendingString: (B)]
NSString * myString = @ "This"; NSString * test = AS (myString, @ "เป็นเพียงการทดสอบ");

บันทึก:

หากใช้มาโครแน่นอนว่าใช้กับอาร์กิวเมนต์ที่หลากหลายดูคำตอบของ EthanB


เย็น! ฉันยังคิดว่า Util ด้านบนเป็นทางออกที่สง่างามกว่ามาก คุณสามารถต่อท้ายสตริงเดียวได้ด้วยแมโครนี้ใช่ไหม
typeoneerror

1
True, AS มาโครด้านบนจะผนวกหนึ่งรหัสต่อหนึ่งบรรทัด หากการผนวกหลาย ๆ อันเป็นความต้องการร่วมกันคุณสามารถสร้างมาโครได้มากขึ้น ตัวอย่างเช่นแมโครเพื่อผนวกสองสตริง: <pre> #define A2S (A, B, C) [[(A) stringByAppendingString: (B)] stringByAppendingString: (C)] </pre>

2
หรือย่อการพิมพ์ที่ต้องการด้วยแมโครอย่างเช่น "#define AS stringByAppendingString" จากนั้นใช้ "AS" ซึ่งปกติแล้วคุณจะพิมพ์ "stringByAppendingString" และสนุกกับการผนวกรหัสต่อบรรทัดหลายบรรทัด

15
ปัญหาเกี่ยวกับมาโครเหล่านี้คือพวกเขาทำลายเป้าหมายหลักอย่างหนึ่งของ Objective-C ซึ่งสามารถอ่านได้ มันไม่มีความชัดเจนอย่างมากในสิ่งที่ "AS" ทำ การบันทึกการกดแป้นบางครั้ง (ส่วนใหญ่จัดการด้วยการเติมข้อความอัตโนมัติ) โดยที่ค่าใช้จ่ายในการอ่านได้นั้นไม่ค่อยจะดีนัก มีข้อยกเว้น (ไวยากรณ์ @ "" สามารถอ่านได้ง่ายกว่าการใช้ + stringWithUTF8String: ทุกครั้ง) แต่เป้าหมายยังควรอ่านได้ง่ายกว่าความกะทัดรัด คุณเขียนหนึ่งครั้ง แต่คุณจะดีบักตลอดไป
Rob Napier

สวัสดี Rob - ฉันไม่เห็นด้วยกับคุณในเรื่องนี้ แน่นอนว่า "AS" เป็นชื่อที่ไม่ดี มันควรจะมีชื่อว่า "CAT"
Fattie

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];

11

นี่เป็นวิธีง่ายๆโดยใช้ไวยากรณ์ตัวอักษรอาร์เรย์ใหม่:

NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""];
                  ^^^^^^^ create array ^^^^^
                                               ^^^^^^^ concatenate ^^^^^

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

หลังจากสองสามปีที่ผ่านมากับ Objective CI คิดว่านี่เป็นวิธีที่ดีที่สุดในการทำงานกับ Objective C เพื่อบรรลุสิ่งที่คุณพยายามจะบรรลุ

เริ่มต้นการป้อนใน "N" ในแอปพลิเคชัน Xcode ของคุณและเติมข้อความอัตโนมัติให้เป็น "NSString" ป้อน "str" ​​และจะเติมข้อความอัตโนมัติให้กับ "stringByAppendingString" การกดแป้นจึงค่อนข้าง จำกัด

เมื่อคุณกดปุ่ม "@" และแท็บขั้นตอนการเขียนโค้ดที่อ่านได้จะไม่มีปัญหาอีกต่อไป มันเป็นเพียงเรื่องของการปรับตัว


คุณรู้ว่าคุณกำลังแนะนำสิ่งที่แน่นอนที่เขาไม่ต้องการทำใช่ไหม?
ผู้ใช้ที่ไม่ใช่ผู้ใช้

8

วิธีเดียวที่จะทำให้c = [a stringByAppendingString: b]ข้อความสั้นลงคือใช้การเติมข้อความอัตโนมัติที่stจุด +ผู้ประกอบการเป็นส่วนหนึ่งของซีซึ่งไม่ทราบเกี่ยวกับวัตถุ Objective-C


คุณรู้ว่าคุณกำลังแนะนำสิ่งที่แน่นอนที่เขาไม่ต้องการทำใช่ไหม? อย่างน้อยที่สุด a #defineสามารถใช้เพื่อทำให้สั้นลงได้
ผู้ใช้ที่ไม่ใช่ผู้ใช้

8

วิธีย่อให้สั้นลงstringByAppendingStringและใช้#define :

#define and stringByAppendingString

ดังนั้นคุณจะใช้:

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

ปัญหาคือมันใช้งานได้กับสองสายเท่านั้นคุณจะต้องใส่วงเล็บเพิ่มเติมสำหรับการผนวกเพิ่มเติม:

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

XCode7 จะไม่ให้คุณใช้ตัวเลือกนี้อีกต่อไป - พูดว่า "และ" เป็นคำสงวน อย่างไรก็ตามคุณสามารถใช้ "cat" แทน conCATenation ฉันทำและวิธีการแก้ปัญหาของคุณทำงานอย่างสมบูรณ์และง่ายมาก
Volomike


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];

6

ฉันลองรหัสนี้ มันใช้งานได้สำหรับฉัน

NSMutableString * myString=[[NSMutableString alloc]init];
myString=[myString stringByAppendingString:@"first value"];
myString=[myString stringByAppendingString:@"second string"];

2
นี่คือการละเมิด NSMutableString ที่เลวร้ายที่สุดเท่าที่เคยมีมา จุดทั้งหมดของ NSMutableString คือคุณไม่ต้องการวิธีการสร้างสตริง autoreleased แต่สามารถแก้ไขสตริงเองได้
gnasher729

ตกลง. ในการใช้งานอย่างน้อยถ้าคุณกำลังใช้appendString: NSMutableString
ผู้ใช้ที่ไม่ใช่ผู้ใช้

6

ลองทำสิ่งต่อไปนี้ในlldbบานหน้าต่าง

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

ข้อผิดพลาดใด

ใช้การจัดสรรและinitWithFormatวิธีการแทน:

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

1
... หวังว่าฉันจะมีชื่อเสียงพอที่จะแสดงความคิดเห็น แต่หวังว่านี่จะช่วยคนอื่นได้
Anthony De Souza

4

นี่คือการบันทึกที่ดีกว่าและการบันทึกเท่านั้น - ขึ้นอยู่กับ dicius excellent หลายวิธีอาร์กิวเมนต์ ฉันกำหนดคลาส Logger และเรียกมันว่า:

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

เกือบดียกเว้นต้องจบ var args ด้วย "nil" แต่ฉันคิดว่ามันไม่มีวิธีแก้ไขใน 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 

เพื่อที่จะเพียงconcatสตริงผมกำหนดหมวดหมู่ใน NSString และเพิ่มวิธีการแบบคงที่ (+) concatenate ไปว่ามีลักษณะเหมือนกันวิธีการบันทึกดังกล่าวข้างต้นยกเว้นว่ามันจะส่งกลับสตริง อยู่ใน NSString เพราะเป็นวิธีสตริงและเป็นแบบสแตติกเพราะคุณต้องการสร้างสตริงใหม่จากสตริง 1-N ไม่เรียกใช้บนสตริงใด ๆ ที่เป็นส่วนหนึ่งของการต่อท้าย


4
NSNumber *lat = [NSNumber numberWithDouble:destinationMapView.camera.target.latitude];
NSNumber *lon = [NSNumber numberWithDouble:destinationMapView.camera.target.longitude];
NSString *DesconCatenated = [NSString stringWithFormat:@"%@|%@",lat,lon];

3

ลองใช้ stringWithFormat:

NSString *myString = [NSString stringWithFormat:@"%@ %@ %@ %d", "The", "Answer", "Is", 42];

ทำไมถึงมี downvote 2 ตัว เป็นเพราะนี่ถูกกล่าวถึงแล้วในคำตอบอื่นหรือไม่
Reimius

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()];

3

วิธีที่ฉันชอบคือ:

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

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

คุณสามารถทำได้โดยเพิ่มวิธีการเข้าร่วมกับ NSArray ด้วยหมวดหมู่:

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

@[]มันเป็นคำจำกัดความสั้น ๆ สำหรับNSArrayฉันคิดว่านี่เป็นวิธีที่เร็วที่สุดในการเชื่อมสตริงเข้าด้วยกัน

หากคุณไม่ต้องการใช้หมวดหมู่ให้ใช้componentsJoinedByString:วิธีการโดยตรง:

NSString *joinedString = [@[firstString, secondString, thirdString] componentsJoinedByString:@""];

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];

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" แทน "และ"


ทำอย่างไร เช่น: sTest3 = sTest1 + sTest2;

@ user285594 นั่นคือประเด็นของคำถาม: ไวยากรณ์ที่ไม่ได้รับอนุญาตใน Objective-C ดูคำตอบอื่น ๆ
ผู้ใช้ที่ไม่ใช่ผู้ใช้

1

สำหรับผู้ชื่นชอบ Objective C ทุกคนที่ต้องการสิ่งนี้ในการทดสอบ UI:

-(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];
}


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:@", "];
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.