Skróty w celu C do łączenia NSStrings

1129

Czy stringByAppendingString:w Objective-C są jakieś skróty do konkatenacji ciągów znaków ( ) lub skróty do NSStringogólnej pracy z nimi ?

Na przykład chciałbym zrobić:

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

coś więcej jak:

string myString = "This";
string test = myString + " is just a test";
typoneerror
źródło
4
Chciałbym tylko zaproponować „@ +” jako operator konkatenacji. Spodziewam się tego w następnej aktualizacji Objective-C, kthxbai
powerj1984 15.01.2013
44
@NicolasMiari Nie jest to jedyna funkcja, której brakuje w Objective-C. Istnieją dziesiątki innych. Cytując z linku Jordão napisał: „Cel-C jest, mówiąc wprost , prymitywnym językiem. Porównaj go z dowolnym nowoczesnym językiem, a szybko okaże się, że go brakuje”. Zgadzam się. Cel C (wczesne lata 80.) to C (wczesne lata siedemdziesiąte) z dodatkiem bardzo prostego i niezbyt bezpiecznego typu OOP. Jest ok, ale w porównaniu z Javą lub C # wydaje się bardzo staromodny.
jcsahnwaldt mówi GoFundMonica
5
@NicolasMiari: Zinterpretowany język? C # i Java to języki kompilowane. Kompilowany do kodu bajtowego, który jest następnie kompilowany ponownie do kodu maszynowego.
Joren
3
Teraz wszystko się zmieniło: Swift (nowy język jabłka) jest prostszy
Pradeep
6
Jeśli chodzi o „bezpieczeństwo typu”, myślę, że to problem stylu. Dla kogoś pochodzącego z C # / C ++ posiadanie heterogenicznych tablic obiektów dowolnego typu może wydawać się dziwne, ale dla kogoś przyzwyczajonego do Objective-C / Cocoa, jest to forma dynamizmu i wolności; jest to zaleta pod warunkiem, że wiesz, co robisz. Jak prawie wszystko w C, które młodsi programiści bashują w dzisiejszych czasach ...
Nicolas Miari

Odpowiedzi:

616

Dwie odpowiedzi, o których mogę myśleć ... żadna nie jest tak przyjemna jak posiadanie operatora konkatenacji.

Najpierw użyj metody NSMutableString, która ma appendStringmetodę, eliminując część potrzeby stosowania dodatkowych ciągów temp.

Po drugie, użyj NSArraydo konkatenacji componentsJoinedByStringmetodą.

Chris Blackwell
źródło
34
Chociaż druga opcja ma wiele pozytywnych opinii, myślę, że jest to najlepsza odpowiedź, jeśli nie znasz wszystkich swoich ciągów konstrukcyjnych. Za każdym razem, gdy dodajesz ciąg, tworzysz dużo narzutu. Użycie zmiennego ciągu usuwa ten problem.
Eli,
22
+1 Zgadzam się w @Eli. Są to ogólnie najlepsze rozwiązania. NSArray -componentsJoinedByString można całkiem dobrze zrobić w jednym wierszu: string = [[NSArray arrayWithObjects: @ "This", "Is", "A", "Test", zero] componentsJoinedByString: @ ""];
Rob Napier
4
+1 za tę odpowiedź. [NSMutableString appendString]jest bardziej przyjazny dla pamięci niż [NSString stringByAppendingStrings].
Pierre-David Belanger,
2
@RobNapier: Teraz dzięki nowej składni dosłownej tablicy jest jeszcze lepiej.
Amogh Talpallikar
27
[NSString stringWithFormat:@"%@/%@/%@", three, two, one];Technika wydaje się najbardziej eleganckie. To powinna być wybrana odpowiedź.
ekillaby
1129

Opcja:

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

Inna opcja:

Zgaduję, że nie jesteś zadowolony z wielu dodatków (a + b + c + d), w którym to przypadku możesz zrobić:

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

używając czegoś takiego

+ (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;
}
diciu
źródło
8
@pablasso Zgoda. Metoda Util jest dość brzydka. Jeśli chcesz czegoś takiego, należy to zrobić jako kategorię NSString o nazwie takiej jak + stringByAppendingStrings :. Nawet prosta funkcja o nazwie takiej jak NSStringForAppendedStrings (...) byłaby lepsza niż metoda statyczna w klasie takiej jak Util (wszystko z „Util” w nazwie jest prawdopodobnie słabo uwzględnione). Funkcja jest również lepiej zaimplementowana za pomocą NSMutableString i -appendString, aby uniknąć tworzenia nieograniczonego zestawu tymczasowo automatycznie wydanych NSStrings.
Rob Napier
1
Przy dużych ciągach może to marnować pamięć. Zalecane jest coś bardziej jak StringBuilder w prawdziwych językach programowania. Następnie możesz po prostu dowiedzieć się, ile pamięci jest potrzebne, zanim zaczniesz dodawać. Powyższe podejście można by zrefaktoryzować, aby to zrobić. Lepiej byłoby jednak utworzyć obiekt StringBuilder, ponieważ dzięki temu użytkownik nie musiałby śledzić listy wszystkich potrzebnych ciągów.
George,
jak importujesz Util? to IDE jest frustrujące (nie sugeruję „importuj coś do góry” jak w przypadku zaćmienia i nigdzie nie znajduję wzmianki o „Util”. Czy to jest klasa, którą powinienem sam kodować?
Gubatron
stringWithFormat jest nie tylko bardzo elegancki, ale także znacznie potężniejszy. Używasz go z @ "% @% @" do łączenia dwóch ciągów, @ "% @% @% @" do łączenia trzech ciągów, ale możesz wstawić dodatkowe znaki, drukować numery, zmieniać kolejność parametrów, jeśli chcesz i tak dalej . Ciąg formatu można zlokalizować, dzięki czemu jest dziesięć razy mocniejszy. Łączenie łańcuchów jest dla początkujących.
gnasher729
150

Jeśli masz 2 literały NSString , możesz również po prostu to zrobić:

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

Przydaje się to również przy dołączaniu do #defines:

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

Cieszyć się.

Johannes Fahrenkrug
źródło
13
@ CristiBăluță :) Ale działa to tylko z literałami, a nie z dynamicznie tworzonymi instancjami NSString.
Johannes Fahrenkrug
9
Właściwie nie potrzebujesz @sznurków po pierwszym. @"I" " really" " enjoy"...
Kevin
Prawdopodobnie powinieneś umieścić STRINGA i STRINGB w nawiasie, w przeciwnym razie możesz uzyskać dziwne wyniki po rozwiązaniu makra. # zdefiniować DOŁĄCZONY (STRINGA STRINGB)
digory doo
@JohannesFahrenkrug Więc dlaczego to NSString* const SQL_CREATE_TABLE_str = @"CREATE TABLE IF NOT EXISTS " TABLE_NAME @" (...);";nie działa? Mam Expected '@' in programbłąd :(
Vagif
@Vagif jak to jest TABLE_NAMEzdefiniowane?
Johannes Fahrenkrug
75

Powracam do tego postu i zawsze kończę sortowanie odpowiedzi, aby znaleźć to proste rozwiązanie, które działa z tyloma zmiennymi, ile potrzeba:

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

Na przykład:

NSString *urlForHttpGet = [NSString stringWithFormat:@"http://example.com/login/username/%@/userid/%i", userName, userId];
Kyle Clegg
źródło
48

Utwórz metodę:

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

Następnie, w dowolnej funkcji, w której jest to potrzebne, ustaw łańcuch lub pole tekstowe lub cokolwiek na wartość zwracaną przez tę funkcję.

Lub, aby utworzyć skrót, przekonwertuj NSString na ciąg C ++ i użyj tam znaku „+”.

Sidd Menon
źródło
To najprostsze rozwiązanie.
GeneCode,
44

Dobrze, że jelita grubego jest rodzajem specjalnym symbolem, ale jest częścią podpisu metodzie możliwe jest exted NSStringz kategorii, aby dodać ten zakaz idiomatyczne styl łańcuchów znaków:

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

Możesz zdefiniować tyle argumentów oddzielonych dwukropkami, ile uznasz za przydatne ... ;-)

Dla pewności dodałem również concat:zmienne argumenty, które pobierają nilzakończoną listę ciągów.

//  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);
}
Palimondo
źródło
20
Głosowałem za tym rok temu, ponieważ nie jest to bardzo dobra odpowiedź. Aby poradzić sobie z konkatenacją dużej liczby ciągów, implementacja Palimondo wymaga albo implementacji dużej liczby bardzo podobnych metod, albo kilkakrotnego wywołania tych metod, co powoduje powstanie dużej części kodu, który zasadniczo po prostu łączy łańcuchy. Stosując to podejście, nie zyskujesz żadnej przewagi nad prostym stringWithFormat:. Nie wspominając o braku nazwanych parametrów, który jest nie tylko niestandardowy, ale także mylący.
FreeAsInBeer
2
Pierwotny pytający wspomniał stringByAppendingStringi nigdy nie mówił nic o używaniu więcej niż dwóch argumentów. Podoba mi się ta odpowiedź bardziej niż zaakceptowana. To całkiem sprytne.
sudo
32

Użyj stringByAppendingString:tego sposobu:

NSString *string1, *string2, *result;

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

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

LUB

result = [result stringByAppendingString:@"This is "];
result = [result stringByAppendingString:@"my string."];
Taimur Ajmal
źródło
34
Zdajesz sobie sprawę, że jesteś sugerujące dokładną rzeczą, jakiej pragnął nie robić, prawda?
SilverSideDown
tyle przecieków!
RamGrg
30

Makro:

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

Przypadki testowe:

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

Alternatywne makro: (jeśli chcesz wymusić minimalną liczbę argumentów)

// 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:@""];
EthanB
źródło
2
Od jakiegoś czasu nie sprawdzałem tego pytania, ale skłaniam się ku zaakceptowaniu tego jako właściwej odpowiedzi po tylu latach!
typeoneerror
1
Prawdopodobnie ma to również lepsze zachowanie niż -[NSString stringByAppendingString:]w tym przypadku użycia - z tym pierwszym otrzymasz wyjątek, jeśli argument jest, nilale nie, jeśli odbiornik jest. Możliwe więc, że 50% szans na błąd w twoim podajniku łańcuchowym zawiedzie cicho i 50% na wyjątek. Dzięki temu stringConcatmasz gwarancję wyjątku w dowolnym nilmiejscu na liście. Co przynajmniej jest bardziej przewidywalne.
Tommy,
27

Podczas budowania żądań usług internetowych uważam, że wykonanie czegoś takiego jest bardzo łatwe i sprawia, że ​​konkatenacja jest czytelna w 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>"
};
FreeAsInBeer
źródło
W przypadku nooba celu-c można wyjaśnić, co robi ta składnia? Czy to tworzy tablicę ciągów i jakoś je łączy? Odniesienie do jakichkolwiek dokumentów też byłoby fajne.
Norman H
2
@NormanH: To jest właściwie część języka C. Po trochę kopania, udało mi się znaleźć to . Stwierdzono w fazie „Łączenie łańcuchów”: Wszystkie sąsiadujące łańcuchy literałów i łańcuchów szerokich są łączone. Na przykład „Łańcuch” „Konkatenacja” staje się „Łańcuch konkatenacji”.
FreeAsInBeer
27

Skrót przez utworzenie makra AppendString (AS) ...

# zdefiniować AS (A, B) [(A) stringByAppendingString: (B)]
NSString * myString = @ "This"; NSString * test = AS (myString, @ „to tylko test”);

Uwaga:

Jeśli używasz makra, oczywiście po prostu rób to z argumentami variadic, zobacz odpowiedź EthanB.

etarion
źródło
Fajne! Nadal uważam, że powyższy Util jest znacznie bardziej eleganckim rozwiązaniem; do tego makra możesz dołączyć tylko jeden ciąg, prawda?
typeoneerror
1
To prawda, że ​​powyższe makro AS dodaje jeden wiersz na wiersz kodu. Jeśli często występuje wiele dodatków, można utworzyć więcej makr. Na przykład makro do dołączenia dwóch ciągów: <pre> # zdefiniuj A2S (A, B, C) [[(A) stringByAppendingString: (B)] stringByAppendingString: (C)] </pre>
2
Lub po prostu skróć wymagane pisanie za pomocą makra, takiego jak „#define AS stringByAppendingString”, a następnie po prostu użyj „AS”, gdzie normalnie wpisz „stringByAppendingString” i ciesz się wieloma dodatkami w wierszu kodu.
15
Problem z tymi makrami polega na tym, że podważają one jeden z głównych celów Celu C, którym jest czytelność. Niezwykle niejasne jest to, co robi „AS”. Zapisanie kilku naciśnięć klawiszy (z których większość jest obsługiwana z autouzupełnianiem) kosztem czytelności rzadko jest dobrym kompromisem. Są wyjątki (składnia @ "" jest znacznie bardziej czytelna niż konieczność używania + stringWithUTF8String: za każdym razem), ale celem powinna być nadal czytelność, a nie tylko zwięzłość. Piszesz raz, ale debugujesz na zawsze.
Rob Napier
Cześć Rob - nie mogę się z tym zgodzić. Jasne, „AS” to złe imię. Może być nazwany być może „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];
koder284
źródło
11

Oto prosty sposób, używając nowej składni literału tablicowego:

NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""];
                  ^^^^^^^ create array ^^^^^
                                               ^^^^^^^ concatenate ^^^^^
justin
źródło
9
NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];

Po kilku latach pracy z Objective CI myśl, że jest to najlepszy sposób pracy z Celem C, aby osiągnąć to, co próbujesz osiągnąć.

Zacznij wpisywać „N” w swojej aplikacji Xcode, a automatycznie uzupełni się do „NSString”. wpisz „str” i automatycznie uzupełnia się do „stringByAppendingString”. Więc naciśnięcia klawiszy są dość ograniczone.

Po opanowaniu naciskania klawisza „@” i pisaniu na klawiaturze proces pisania czytelnego kodu nie staje się już problemem. To tylko kwestia dostosowania.

Ian Clay
źródło
Zdajesz sobie sprawę, że jesteś sugerujące dokładną rzeczą, jakiej pragnął nie robić, prawda?
Użytkownik niebędący użytkownikiem
8

Jedynym sposobem c = [a stringByAppendingString: b]skrócenia jest użycie autouzupełniania w dowolnym stmomencie. +Operator jest częścią C, która nie wie o obiektach Objective-C.


źródło
Zdajesz sobie sprawę, że jesteś sugerujące dokładną rzeczą, jakiej pragnął nie robić, prawda? Przynajmniej #definemożna go użyć do skrócenia.
Użytkownik niebędący użytkownikiem
8

Co powiesz na skrócenie stringByAppendingStringi użycie #define :

#define and stringByAppendingString

Zatem użyłbyś:

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

Problem polega na tym, że działa tylko dla dwóch ciągów, musisz owinąć dodatkowe nawiasy, aby uzyskać więcej dodatków:

NSString* myString = [[@"Hello" and: @" world"] and: @" again"];
Niedziela Żelazna Stopa
źródło
XCode7 nie pozwala już korzystać z tej opcji - mówi „a” to słowo zastrzeżone. Możesz jednak użyć „cat” zamiast tego, do CONCATenation. Zrobiłem to, a twoje rozwiązanie działa idealnie i jest niezwykle proste.
Volomike,
8
NSString *result=[NSString stringWithFormat:@"%@ %@", @"Hello", @"World"];
Gobi M.
źródło
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];
aleemb
źródło
6

Próbowałem tego kodu. zadziałało dla mnie.

NSMutableString * myString=[[NSMutableString alloc]init];
myString=[myString stringByAppendingString:@"first value"];
myString=[myString stringByAppendingString:@"second string"];
Erhan Demirci
źródło
2
To najgorsze nadużycie NSMutableString w historii. Chodzi o to, że NSMutableString nie wymaga metod tworzenia automatycznie wydanych ciągów, ale może modyfikować sam ciąg.
gnasher729
Zgodzić się. Przynajmniej użyj, appendString:jeśli używasz NSMutableString.
Użytkownik niebędący użytkownikiem
6

Próbowałem następujące w lldbokienku

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

które błędy.

zamiast tego użyj przydziału i initWithFormatmetody:

[[NSString alloc] initWithFormat:@"%@/%@/%@", @"three", @"two", @"one"];
Anthony De Souza
źródło
1
... żałuję, że nie mam dość reputacji, by komentować, ale mam nadzieję, że to pomoże komuś innemu.
Anthony De Souza,
4

Ma to na celu lepsze rejestrowanie i rejestrowanie tylko - w oparciu o doskonałą metodę wielu argumentów dicius. Definiuję klasę Logger i nazywam ją tak:

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

Prawie dobrze, z wyjątkiem konieczności kończenia var argumentów na „zero”, ale przypuszczam, że nie ma takiej możliwości w 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 

Aby tylko konkatować łańcuchy, zdefiniowałbym kategorię na NSString i dodałbym do niej statyczną (+) metodę konkatenacji, która wygląda dokładnie tak, jak metoda log powyżej, z tym wyjątkiem, że zwraca łańcuch. Działa na NSString, ponieważ jest to metoda łańcuchowa, i jest statyczna, ponieważ chcesz utworzyć nowy ciąg z ciągów 1-N, a nie wywoływać go na żadnym z ciągów, które są częścią append.

n13
źródło
4
NSNumber *lat = [NSNumber numberWithDouble:destinationMapView.camera.target.latitude];
NSNumber *lon = [NSNumber numberWithDouble:destinationMapView.camera.target.longitude];
NSString *DesconCatenated = [NSString stringWithFormat:@"%@|%@",lat,lon];
Avinash Mishra
źródło
3

Wypróbuj stringWithFormat:

NSString *myString = [NSString stringWithFormat:@"%@ %@ %@ %d", "The", "Answer", "Is", 42];
Dowódca HK
źródło
Dlaczego ma to 2 głosy negatywne? Czy to dlatego, że zostało to już wspomniane w innej odpowiedzi?
Reimius
3

Podczas pracy z łańcuchami często łatwiej jest utworzyć plik źródłowy ObjC ++, a następnie mogę połączyć std :: strings przy użyciu drugiej metody przedstawionej w pytaniu.

std::string stdstr = [nsstr UTF8String];

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

NSString* nsstr = [NSString stringWithUTF8String:stdstr.c_str()];
iforce2d
źródło
3

Moja preferowana metoda to:

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

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

Możesz to osiągnąć, dodając metodę łączenia do NSArray z kategorią:

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

@[] jest to krótka definicja dla NSArray , myślę, że jest to najszybsza metoda łączenia łańcuchów.

Jeśli nie chcesz korzystać z kategorii, użyj bezpośrednio componentsJoinedByString:metody:

NSString *joinedString = [@[firstString, secondString, thirdString] componentsJoinedByString:@""];
LombaX
źródło
3

Możesz użyć NSArray jako

NSString *string1=@"This"

NSString *string2=@"is just"

NSString *string3=@"a test"  

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

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

lub

możesz użyć

NSString *imageFullName=[NSString stringWithFormat:@"%@ %@ %@.", string1,string2,string3];
Bieg
źródło
1

Każdy z tych formatów działa w XCode7 podczas testowania:

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

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

Z jakiegoś powodu potrzebujesz tylko operatora @ w pierwszym ciągu miksu.

Jednak nie działa przy wstawianiu zmiennych. W tym celu możesz użyć tego niezwykle prostego rozwiązania, z wyjątkiem makra na „cat” zamiast „i”.

Volomike
źródło
jak to zrobić? np .: sTest3 = sTest1 + sTest2;
@ user285594 To było sedno pytania: ta składnia jest niedozwolona w Objective-C. Zobacz inne odpowiedzi.
Użytkownik niebędący użytkownikiem
1

Dla wszystkich miłośników Celu C, którzy potrzebują tego w teście interfejsu użytkownika:

-(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];
}
netshark1000
źródło
0
listOfCatalogIDs =[@[@"id[]=",listOfCatalogIDs] componentsJoinedByString:@""];
użytkownik4951
źródło
0

Wyobraźmy sobie, że nie wiesz, ile tam jest łańcuchów.

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:@", "];
Resty
źródło