iPhone: огромный всплеск памяти при создании цикла NSString - PullRequest
3 голосов
/ 15 марта 2012

У меня проблема с памятью, которая приводит к сбою. Я перебираю массив словарей и затем внутри него я перебираю созданный мной массив ключей. Я использую каждый ключ в этом массиве ключей, чтобы получить значение этого ключа в словаре. Затем я создаю строку, добавляя значения. Эта строка будет содержать большой объем данных.

Я также использую ARC, поэтому не могу разблокировать вручную.

Пик памяти происходит в строке stringByAppendingFormat.

    NSString *theString = [[NSString alloc] init];
for (NSMutableDictionary *aDict in collectionArray)
{
    for (NSString *key in itemKeys)
    {
        NSString *valueString = [aDict valueForKey:key];

        // Memory spikes here
        theString = [theString stringByAppendingFormat:@"%@,", valueString];
    }
}

Ответы [ 2 ]

7 голосов
/ 15 марта 2012

Вместо NSString, вы должны использовать NSMutableString.Попробуйте это:

NSMutableString *theString = [[NSMutableString alloc] init];
for (NSMutableDictionary *aDict in collectionArray)
{
    for (NSString *key in itemKeys)
    {
        NSString *valueString = [aDict valueForKey:key];

        // Memory spikes here
        [theString appendFormat:@"%@,", valueString];
    }
}

Редактировать: Это, вероятно, решит ваши проблемы, если ваш словарь и длина itemKeys не особенно велики.Однако, если они большие, вам нужно будет использовать автозапуск в вашем цикле, как они делают здесь: https://stackoverflow.com/a/7804798/211292 Также рассмотрите изменение Томми, если все, что вы делаете, это разделяете значения запятыми.

4 голосов
/ 15 марта 2012

Оставляя в стороне вопросы, ответы на которые были даны в другом месте, - что вы постоянно создаете новую строку, которая включает в себя старую плюс некоторую дополнительную, оставляя старую в пуле автоматического выпуска, которая не будет стерта по крайней мере, пока вы не выйдете из метода - следующее:

NSArray *values = [aDict objectsForKeys:itemKeys notFoundMarker:@""];
theString = [values componentsJoinedByString:@","];

Казалось бы, делать то, что вы хотите (ну, если вы добавите дополнительную запятую в конце) без какого-либо явного вида внутреннего цикла.

...