Objective-C, Построение строки, обзор кода - PullRequest
1 голос
/ 21 сентября 2011

Этот код работает нормально, но каждый раз, когда я смотрю на него, я умираю немного внутри.: (

Можете ли вы помочь мне немного его упростить?

Есть ли более элегантный способ .append (SomeString)? (Чтобы дать вам некоторую перспективу, код печатает элементы связанного списка)

- (NSString *) description {      
    Node* tempNode = [self firstNode];

    if (tempNode == nil) {
        return @"List contains no elements";
    }

    NSString *desc= [[NSString alloc] initWithString:@"(null) -- "];
    desc = [desc stringByAppendingString:[firstNode nodeCharacter]];
    desc = [desc stringByAppendingString:@" -- "];

    while ([tempNode nextNode] != nil) {
        desc =  [desc stringByAppendingString:[[tempNode nextNode]nodeCharacter]];
        desc =  [desc stringByAppendingString:@" -- "];
        tempNode = [tempNode nextNode];
    }

    return [desc stringByAppendingString:@" (null)"];


}

Ответы [ 5 ]

3 голосов
/ 21 сентября 2011
  • Прежде всего, если вы хотите создать строку шаг за шагом или изменить ее, прекратите использовать stringByAppendingString: и используйте NSMutableString вместо NSString !!!

  • Тогда, по вашему усмотрению, вы даже можете использовать stringWithFormat: для создания части вашей строки.

  • Наконец, вы забыли управлять своей памятью: вы выделяете / инициализируете свою строку, но никогда не освобождаете ее (и когда вы переназначаете переменную desc через строку, вы теряете отслеживание выделенной памяти и получаете утечку .

Итак, вот пересмотренный код:

- (NSString *) description {      
  Node* tempNode = [self firstNode];

  if (tempNode == nil) {
    return @"List contains no elements";
  }

  NSMutableString *desc = [NSMutableString stringWithFormat:@"(null) -- %@ -- ",[firstNode nodeCharacter]];
  while ((tempNode = [tempNode nextNode]) != nil) {
    [desc appendFormat:@"%@ -- ",[tempNode nodeCharacter]];
  }
  [desc appendingString:@" (null)"];

  return desc;
}

(Обратите внимание, что вы также можете создать NSArray из узлов вашего списка и использовать componentsJoinedByString, затем в конце ... так что у вас все равно есть несколько возможностей)

1 голос
/ 21 сентября 2011

Вместо того, чтобы использовать цикл while, взгляните на Быстрое перечисление Какао .Он уже поддерживается NSArrays и позволяет вам быстро перечислять элементы массива:

for (id object in myArray)
    // Do something with object

Вы можете применить быстрое перечисление (или использовать NSEnumerator) в элементах вашего узла, а затем выполнить цикл по ним:

// Use mutable strings
NSMutableString *desc = [[NSMutableString alloc] initWithString:@"(null) -- "];
for (Node *node in nodeList) {
    [desc appendString:[node nodeCharacter];
    [desc appendString:@" -- "];
}
return [desc stringByAppendingString:@" (null)"];
1 голос
/ 21 сентября 2011

Да, используйте NSMutableString, что потребует гораздо меньше памяти.

- (NSString *) description {      
    Node* tempNode = [self firstNode];
    if (tempNode == nil) {
        return @"List contains no elements";
    }

    //Autorelease string to prevent memory leak
    NSMutableString *desc= [NSMutableString stringWithString:@"(null) -- "];
    [desc appendString:[firstNode nodeCharacter]];
    [desc appendString:@" -- "];

    while ([tempNode nextNode] != nil) {
        [desc appendString:[[tempNode nextNode]nodeCharacter]];
        [desc appendString:@" -- "];
        tempNode = [tempNode nextNode];
    }

    [desc appendString:@" (null)"];
    return desc;
}
1 голос
/ 21 сентября 2011

Вы смотрели на NSMutableString ? Он имеет -appendString: методы.

Редактировать: Вы также можете использовать рекурсивную функцию на своем узле для обхода списка и построения строки. Я бы сделал какой-нибудь простой публичный метод, например - (NSString *)description, чтобы вызвать первый метод, а затем использовать закрытый метод для выполнения вашей грязной работы, например:

- (NSString *)recursiveDescriptionWithSubnode:(Node *)node {
    if(!node) {
        return [self nodeCharacter];
    }
    else {
        return [[self nodeCharacter] stringByAppendingString:[self recursiveDescriptionWithSubnode:[self nextNode]];
    }
}

Обратите внимание, что это не хвостовая рекурсия, и поэтому для длинного списка это приведет к созданию значительного пула автоматического выпуска и стека вызовов. Создание рекурсивного хвоста оставлено читателю в качестве упражнения (но вы можете использовать NSMutableString для этого).

0 голосов
/ 21 сентября 2011

Вместо создания строки вы можете создать массив строк, которые в конечном итоге вы получите в виде единой объединенной строки, разделяющей каждое значение строкой "-".

Если вы знаете, сколькоэлементы, которые вы можете иметь, вы можете создать массив с такой емкостью, который может быть немного более эффективным под капотом для NSMutableArray.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...