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

发布于 2024-12-05 18:02:43 字数 777 浏览 0 评论 0原文

这段代码工作得很好,但每次我看到它时,我的内心都会有点崩溃。 :(

你能帮我简化一下吗?

有没有更优雅的方法来 .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)"];


}

This code works fine, but each time i look at it, i die a little bit inside. :(

Can you help me streamline it a bit?

Is there a more elegant way to .append(SomeString)? (To give you some perspective, code prints elements of the Linked List)

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


}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦里兽 2024-12-12 18:02:43
  • 首先,如果你想一步步构建一个字符串或者修改它,停止使用stringByAppendingString:,而使用NSMutableString< /code>而不是 NSString !!!

  • 然后,对于您来说,您甚至可以使用 stringWithFormat: 来构建字符串的一部分。

  • 最后,您忘记了管理内存:您分配/初始化了字符串,但从未释放它(并且当您在后面的行中重新分配 desc 变量时,您失去了分配的内存的跟踪并拥有 最后,您忘记了管理内存

因此这里是修改后的 。 code:

- (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...所以无论如何,您在这里都有多种可能性)

  • First of all, if you want to build a string step by step or modify it, stop using stringByAppendingString:, and use NSMutableString instead of NSString !!!

  • Then, for your matter, you can even use stringWithFormat: to build part of your string.

  • Finally, you forgot to manage your memory: you alloc/init your string but never release it (and as your reassign the desc variable the line after, you loose track of the allocated memory and have a leak.

So here is the revised code:

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

(Note that you may also build an NSArray of the nodes of your list and use componentsJoinedByString then at the end… so you have multiple possibilities here anyway)

小鸟爱天空丶 2024-12-12 18:02:43

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

Yes use an NSMutableString which will involve much less memory allocations.

- (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;
}
与酒说心事 2024-12-12 18:02:43

不要使用 while 循环,请查看 Cocoa 的 快速枚举。 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)"];

Rather than using the while loop, take a look at Cocoa's Fast Enumeration. It is supported by NSArrays already, and allow you to rapidly enumerate through array elements:

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

You can adopt fast enumeration (or use NSEnumerator) in your node elements, then loop through them:

// Use mutable strings
NSMutableString *desc = [[NSMutableString alloc] initWithString:@"(null) -- "];
for (Node *node in nodeList) {
    [desc appendString:[node nodeCharacter];
    [desc appendString:@" -- "];
}
return [desc stringByAppendingString:@" (null)"];
猫卆 2024-12-12 18:02:43

您是否看过 NSMutableString< /a>?它有 -appendString: 方法。

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

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

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

Have you looked at NSMutableString? It has -appendString: methods.

Edit: You could also use a recursive function on your node to traverse the list and build up the string. I would make some simple public method like - (NSString *)description to call the first method and then use a private method internally to do your dirty work, like so:

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

Note that this isn't tail recursive and so for a long list this would build up a sizable autorelease pool and call stack. Making it tail recursive is left as an exercise for the reader (but you could use NSMutableString to do it).

对风讲故事 2024-12-12 18:02:43

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

如果您知道可能有多少个元素,则可以创建具有该容量的数组,这对于 NSMutableArray 来说可能会稍微更有效。

Instead of building up a string, you could create an array of strings, that you ultimately return as a single, joined string separating each value with your " -- " string.

If you know how many elements you might have, you could create the array with that capacity, which might be slightly more efficient under the hood for NSMutableArray.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文