Objective-C,构造一个字符串,代码审查

时间:2011-09-20 21:00:32

标签: objective-c nsstring

这段代码很好用,但每次看一遍,我都会死一点。 :(

你可以帮我简化一下吗?

.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 个答案:

答案 0 :(得分:3)

  • 首先,如果您想逐步构建字符串或修改字符串,停止使用stringByAppendingString: 使用NSMutableString < / strong>而不是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 :(得分:1)

你看过NSMutableString了吗?它有-appendString:methods。

编辑:您还可以在节点上使用递归函数遍历列表并构建字符串。我会做一些简单的公共方法,如- (NSString *)description来调用第一个方法,然后在内部使用私有方法来执行你的脏工作,如下所示:

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

请注意,这不是尾递归,因此对于长列表,这将构建一个相当大的自动释放池和调用堆栈。使尾部递归是留给读者的练习(但你可以用NSMutableString来做)。

答案 2 :(得分:1)

是使用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;
}

答案 3 :(得分:1)

不要使用while循环,而是看看Cocoa的Fast Enumeration。它已经由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)"];

答案 4 :(得分:0)

您可以创建一个字符串数组,而不是构建字符串,最终将返回为一个单独的连接字符串,用“ - ”字符串分隔每个值。

如果您知道可能有多少元素,则可以使用该容量创建数组,这可能会在NSMutableArray的引擎下稍微提高效率。