Ярлыки в Objective-C для объединения строк NSS


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. Есть десятки других. Цитируя ссылку, которую опубликовал Джордао, «Objective-C, если говорить прямо, является примитивным языком. Сравните его с любым современным языком, и вы быстро обнаружите, что его не хватает». Согласен. Objective-C (начало 1980-х) - это C (начало 1970-х) с добавлением очень простого и не очень безопасного типа ООП. Это нормально, но по сравнению с Java или C # это выглядит очень старомодно.
jcsahnwaldt говорит GoFundMonica

5
@NicolasMiari: устный перевод? C # и Java являются скомпилированными языками. Компилируется в байт-код, который затем снова компилируется в машинный код.
Джорен

3
Теперь все изменилось: Swift (новый язык Apple) стал более простым
Pradeep

6
Что касается «безопасности типов», я думаю, что это проблема стиля. Для кого-то из C # / C ++ наличие разнородных массивов объектов любого типа может показаться странным, но для кого-то, привыкшего к Objective-C / Cocoa, это форма динамизма и свободы; это преимущество, если вы знаете, что делаете. Как и почти все о C, которое молодые программисты
бьют в

Ответы:


616

Я могу придумать два ответа ... ни один из них не настолько приятен, как просто наличие оператора конкатенации.

Во-первых, используйте метод NSMutableString, который имеет appendStringметод, устраняющий необходимость в дополнительных временных строках.

Во-вторых, используйте NSArrayконкатенацию через componentsJoinedByStringметод.


34
Хотя у другого варианта есть много положительных отзывов, я думаю, что это лучший ответ, если вы не знаете все свои строки при создании. Каждый раз, когда вы добавляете строку, вы создаете много накладных расходов. Использование изменяемой строки устраняет эту проблему.
Эли

22
+1 Согласен с @Eli. Как правило, это лучшие решения. NSArray -componentsJoinedByString можно довольно хорошо выполнить в одной строке: string = [[NSArray arrayWithObjects: @ "This", "Is", "A", "Test", nil] componentsJoinedByString: @ ""];
Роб Нейпир

4
+1 за этот ответ. [NSMutableString appendString]больше памяти, чем [NSString stringByAppendingStrings].
Пьер-Давид Белэнджер

2
@RobNapier: теперь с новым синтаксисом массива, он стал еще лучше.
Амог Талпалликар

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 Согласен. Метод Util довольно уродлив. Если вам нужна такая вещь, это должно быть сделано как категория NSString с именем вроде + stringByAppendingStrings :. Даже обычная функция с именем, подобным NSStringForAppendedStrings (...), будет лучше, чем статический метод в классе, подобном Util (что-либо с «Util» в имени, вероятно, будет плохо учтено). Функция также лучше реализована с помощью NSMutableString и -appendString, чтобы избежать создания неограниченного набора временных автоматически выпущенных строк NSStrings.
Роб Нейпир

1
С большими строками это может привести к потере памяти. Рекомендуется что-то вроде StringBuilder в реальных языках программирования. Тогда вы могли бы просто выяснить, сколько памяти необходимо, прежде чем вы действительно начнете добавлять. Вышеупомянутый подход может быть изменен, чтобы сделать это. Однако было бы лучше создать объект StringBuilder, так как это избавит пользователя от необходимости отслеживать список всех строк, которые им нужны вместе.
Джордж

как вы импортируете Util? эта среда IDE разочаровывает (нет предложенного «импортировать что-то. Util», как на затмении, и я нигде не упоминаю «Util». Это класс, который я должен сам кодировать?
Gubatron

stringWithFormat не только очень элегантный, но и гораздо более мощный. Вы используете его с @ "% @% @" для объединения двух строк, @ "% @% @% @" для объединения трех строк, но вы можете поместить любые дополнительные символы внутрь, напечатать числа, изменить порядок параметров, если хотите, и так далее , Строка формата может быть локализована, что делает ее в десять раз более мощной. Конкатенация строк для начинающих.
gnasher729

150

Если у вас есть 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

Наслаждаться.


13
@ CristiBăluță :) Но это работает только с литералами, а не с динамически создаваемыми экземплярами NSString.
Йоханнес Фаренкруг

9
Вам на самом деле не нужны @s в строках после первого. @"I" " really" " enjoy"...
Кевин

Возможно, вы захотите поместить STRINGA и STRINGB в круглые скобки, иначе вы можете получить странные результаты при разрешении макроса. #define JOINED (STRINGA STRINGB)
Дигори Ду

@JohannesFahrenkrug Тогда почему это NSString* const SQL_CREATE_TABLE_str = @"CREATE TABLE IF NOT EXISTS " TABLE_NAME @" (...);";не работает? У меня Expected '@' in programошибка :(
Вагиф

@Vagif как TABLE_NAMEопределяется?
Йоханнес Фаренкруг

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категорию with, чтобы добавить этот неидиоматический стиль конкатенации строк:

[@"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, и он никогда не говорил ничего об использовании более двух аргументов. Мне нравится этот ответ лучше, чем принятый. Это довольно умно.
Судо

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

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

Тестовые случаи:

- (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, в любом месте списка. Что, по крайней мере, более предсказуемо.
Томми

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

Для предмета c-noob вы можете объяснить, что делает этот синтаксис? Это создает массив строк и каким-то образом соединяет их? Ссылка на любые документы тоже будет крутой.
Норман Х

2
@NormanH: На самом деле это часть языка Си. После небольшого копания, я был в состоянии найти это . В состоянии «Конкатенация строк» ​​указывается: все смежные строковые и широкие строковые литералы объединяются. Например, «Строка» «Конкатенация» становится «Строка Конкатенация».
FreeAsInBeer

27

Ярлык путем создания макроса AppendString (AS) ...

#define AS (A, B) [(A) stringByAppendingString: (B)]
NSString * myString = @ "This"; NSString * test = AS (myString, @ "это просто тест");

Замечания:

Если вы используете макрос, конечно, просто делайте это с переменными аргументами, смотрите ответ EthanB.


Круто! Я все еще думаю, что Util выше - намного более изящное решение; Вы можете добавить только одну строку с этим макросом, верно?
typeoneerror

1
Правда, макрос AS выше добавляет по одному на строку кода. Если многократное добавление является общей потребностью, то можно создать больше макросов. Например, макрос для добавления двух строк: <pre> #define A2S (A, B, C) [[(A) stringByAppendingString: (B)] stringByAppendingString: (C)] </ pre>

2
Или просто сократите типизацию, необходимую с помощью макроса, подобного «#define AS stringByAppendingString», затем просто используйте «AS» там, где вы обычно набираете «stringByAppendingString», и наслаждайтесь несколькими добавлениями на строку кода.

15
Проблема с этими макросами заключается в том, что они подрывают одну из основных целей Objective-C, которая заключается в удобочитаемости. Крайне непонятно, что делает «КАК». Сохранение нескольких нажатий клавиш (большинство из которых обрабатываются с автозаполнением) за счет читабельности редко является хорошим компромиссом. Существуют исключения (синтаксис @ "" гораздо более читабелен, чем необходимость использовать + stringWithUTF8String: каждый раз), но цель все же должна быть удобочитаемостью, а не просто краткостью. Вы пишете один раз, но вы отлаживаете навсегда.
Роб Нейпир

Привет, Роб, я не могу с тобой согласиться. Конечно, "КАК" это плохое имя. Это должно быть названо, возможно, "CAT".
Толстяк

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 C я думаю, что это лучший способ работать с Objective C, чтобы достичь того, чего вы пытаетесь достичь.

Начните вводить «N» в приложении Xcode, и оно автоматически заполняется до «NSString». введите "str" ​​и он автоматически завершится до "stringByAppendingString". Таким образом, нажатия клавиш довольно ограничены.

Как только вы научитесь нажимать клавишу «@» и вкладывать процесс написания читаемого кода, больше не станет проблемой. Это просто вопрос адаптации.


Вы понимаете, что предлагаете именно то, что он хотел не делать, верно?
Пользователь, который не является пользователем

8

Единственный способ сделать c = [a stringByAppendingString: b]короче - это использовать автозаполнение в stточке. +Оператор является частью С, который не знает об объектах , Objective-C.


Вы понимаете, что предлагаете именно то, что он хотел не делать, верно? По крайней мере, #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 в том, что вам не нужны методы, создающие автоматически освобожденные строки, но вы можете изменить саму строку.
gnasher729

Согласен. По крайней мере, используйте, appendString:если вы используете NSMutableString.
Пользователь, который не является пользователем

6

Пытался следующее в lldbпанели

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

какие ошибки.

вместо этого используйте alloc и initWithFormatметод:

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

1
... хотелось бы, чтобы у меня было достаточно репутации, чтобы комментировать, но надеюсь, что это поможет кому-то еще.
Энтони Де Соуза,

4

Это для лучшей регистрации, и только регистрации - на основе отличного метода множественных аргументов dicius. Я определяю класс Logger и называю его так:

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

Почти хорошо, за исключением необходимости заканчивать аргументы var "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 

Чтобы только конкатировать строки, я бы определил категорию для NSString и добавил к ней статический (+) метод конкатенации, который выглядит точно так же, как метод log выше, за исключением того, что он возвращает строку. Он находится на 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];

Почему это имеет 2 downvotes? Это потому, что это уже упоминалось в другом ответе?
Реймиус

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» вместо «and».


как это сделать? например: sTest3 = sTest1 + sTest2;

@ user285594 В этом и заключался вопрос: этот синтаксис не разрешен в Objective-C. Смотрите другие ответы.
Пользователь, который не является пользователем

1

Для всех любителей Objective C, которые нуждаются в этом в 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];
}


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:@", "];
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.