Reputation: 96391
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)"];
}
Upvotes: 1
Views: 573
Reputation: 32681
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)
Upvotes: 3
Reputation: 5245
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).
Upvotes: 1
Reputation: 16938
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.
Upvotes: 0
Reputation: 16316
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)"];
Upvotes: 1
Reputation: 57169
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;
}
Upvotes: 1