Objective C - Implement a method using an out id* - objective-c

I am currently developing an Objective C class ClassA and I am trying to implement a method similar to NSURL method - (BOOL)getResourceValue:(out id __nullable * __nonnull)value forKey:(NSString *)key error:(out NSError ** __nullable)error that uses out id *:
My Method is: - (BOOL)changeString:(out id *)theString toString:(NSString *)newString
And I want my method to set theString to (NSString*) newString's value
I my method to be used like this:
id inputString;
[[ClassA alloc] changeString:&inputString toString:#"New String"];
inputString should now be set to "New String" (as id *)
How can I do this in - (BOOL)changeString:(out id *)theString toString:(NSString *)newString?
Thanks

This is pretty easy:
- (BOOL)changeString:(NSString * _Nonnull *)theString
toString:(NSString *)newString {
*theString = newString;
return YES;
}
And use it:
NSString *inputString;
BOOL result = [self changeString:&inputString toString:#"Hello World"];
NSLog(#"%d - %#", result, inputString);
inputString is not required to be nil, you can even pass a value
- (BOOL)changeString:(NSString * _Nonnull *)theString
toString:(NSString *)newString {
*theString = [NSString stringWithFormat: #"%# %#", *theString, newString];
return YES;
}
NSString *inputString = #"Hello";
BOOL result = [self changeString:&inputString toString:#"World"];
NSLog(#"%d - %#", result, inputString);

Related

I am trying to pull the value based on the key in a NSArray in Objective-C that are passed in a URL. How do I get the value form the key? [duplicate]

I have an NSURL:
serverCall?x=a&y=b&z=c
What is the quickest and most efficient way to get the value of y?
Thanks
UPDATE:
Since 2010 when this was written, it seems Apple has released a set of tools for that purpose. Please see the answers below for those.
Old-School Solution:
Well I know you said "the quickest way" but after I started doing a test with NSScanner I just couldn't stop. And while it is not the shortest way, it is sure handy if you are planning to use that feature a lot. I created a URLParser class that gets these vars using an NSScanner. The use is a simple as:
URLParser *parser = [[[URLParser alloc] initWithURLString:#"http://blahblahblah.com/serverCall?x=a&y=b&z=c&flash=yes"] autorelease];
NSString *y = [parser valueForVariable:#"y"];
NSLog(#"%#", y); //b
NSString *a = [parser valueForVariable:#"a"];
NSLog(#"%#", a); //(null)
NSString *flash = [parser valueForVariable:#"flash"];
NSLog(#"%#", flash); //yes
And the class that does this is the following (*source files at the bottom of the post):
URLParser.h
#interface URLParser : NSObject {
NSArray *variables;
}
#property (nonatomic, retain) NSArray *variables;
- (id)initWithURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;
#end
URLParser.m
#implementation URLParser
#synthesize variables;
- (id) initWithURLString:(NSString *)url{
self = [super init];
if (self != nil) {
NSString *string = url;
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *tempString;
NSMutableArray *vars = [NSMutableArray new];
[scanner scanUpToString:#"?" intoString:nil]; //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:#"&" intoString:&tempString]) {
[vars addObject:[tempString copy]];
}
self.variables = vars;
[vars release];
}
return self;
}
- (NSString *)valueForVariable:(NSString *)varName {
for (NSString *var in self.variables) {
if ([var length] > [varName length]+1 && [[var substringWithRange:NSMakeRange(0, [varName length]+1)] isEqualToString:[varName stringByAppendingString:#"="]]) {
NSString *varValue = [var substringFromIndex:[varName length]+1];
return varValue;
}
}
return nil;
}
- (void) dealloc{
self.variables = nil;
[super dealloc];
}
#end
*if you don't like copying and pasting you can just download the source files - I made a quick blog post about this here.
So many custom url parsers here, remember NSURLComponents is your friend!
Here is an example where I pull out a url encoded parameter for "page"
Swift
let myURL = "www.something.com?page=2"
var pageNumber : Int?
if let queryItems = NSURLComponents(string: myURL)?.queryItems {
for item in queryItems {
if item.name == "page" {
if let itemValue = item.value {
pageNumber = Int(itemValue)
}
}
}
}
print("Found page number: \(pageNumber)")
Objective-C
NSString *myURL = #"www.something.com?page=2";
NSURLComponents *components = [NSURLComponents componentsWithString:myURL];
NSNumber *page = nil;
for(NSURLQueryItem *item in components.queryItems)
{
if([item.name isEqualToString:#"page"])
page = [NSNumber numberWithInteger:item.value.integerValue];
}
"Why reinvent the wheel!" - Someone Smart
I'm pretty sure you have to parse it yourself. However, it's not too bad:
NSString * q = [myURL query];
NSArray * pairs = [q componentsSeparatedByString:#"&"];
NSMutableDictionary * kvPairs = [NSMutableDictionary dictionary];
for (NSString * pair in pairs) {
NSArray * bits = [pair componentsSeparatedByString:#"="];
NSString * key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString * value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[kvPairs setObject:value forKey:key];
}
NSLog(#"y = %#", [kvPairs objectForKey:#"y"]);
In Swift you can use NSURLComponents to parse the query string of an NSURL into an [AnyObject].
You can then create a dictionary from it (or access the items directly) to get at the key/value pairs. As an example this is what I am using to parse a NSURL variable url:
let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
let items = urlComponents?.queryItems as [NSURLQueryItem]
var dict = NSMutableDictionary()
for item in items{
dict.setValue(item.value, forKey: item.name)
}
println(dict["x"])
I've been using this Category: https://github.com/carlj/NSURL-Parameters.
It's small and easy to use:
#import "NSURL+Parameters.h"
...
NSURL *url = [NSURL URLWithString:#"http://foo.bar.com?paramA=valueA&paramB=valueB"];
NSString *paramA = url[#"paramA"];
NSString *paramB = url[#"paramB"];
You can use Google Toolbox for Mac.
It adds a function to NSString to convert query string to a dictionary.
http://code.google.com/p/google-toolbox-for-mac/
It works like a charm
NSDictionary * d = [NSDictionary gtm_dictionaryWithHttpArgumentsString:[[request URL] query]];
Here's a Swift 2.0 extension that provides simple access to parameters:
extension NSURL {
var params: [String: String] {
get {
let urlComponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false)
var items = [String: String]()
for item in urlComponents?.queryItems ?? [] {
items[item.name] = item.value ?? ""
}
return items
}
}
}
Sample usage:
let url = NSURL(string: "http://google.com?test=dolphins")
if let testParam = url.params["test"] {
print("testParam: \(testParam)")
}
I wrote a simple category to extend NSString/NSURL that lets you extract URL query parameters individually or as a dictionary of key/value pairs:
https://github.com/nicklockwood/RequestUtils
I did it using a category method based on #Dimitris solution
#import "NSURL+DictionaryValue.h"
#implementation NSURL (DictionaryValue)
-(NSDictionary *)dictionaryValue
{
NSString *string = [[self.absoluteString stringByReplacingOccurrencesOfString:#"+" withString:#" "]
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *temp;
NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease];
[scanner scanUpToString:#"?" intoString:nil]; //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:#"&" intoString:&temp])
{
NSArray *parts = [temp componentsSeparatedByString:#"="];
if([parts count] == 2)
{
[dict setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
}
}
return dict;
}
#end
All of the current answers are version specific or needlessly wasteful. Why create a dictionary if you only want one value?
Here's a simple answer that supports all iOS versions:
- (NSString *)getQueryParam:(NSString *)name fromURL:(NSURL *)url
{
if (url)
{
NSArray *urlComponents = [url.query componentsSeparatedByString:#"&"];
for (NSString *keyValuePair in urlComponents)
{
NSArray *pairComponents = [keyValuePair componentsSeparatedByString:#"="];
NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
if ([key isEqualToString:name])
{
return [[pairComponents lastObject] stringByRemovingPercentEncoding];
}
}
}
return nil;
}
You can do that easy :
- (NSMutableDictionary *) getUrlParameters:(NSURL *) url
{
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
NSString *tmpKey = [url query];
for (NSString *param in [[url query] componentsSeparatedByString:#"="])
{
if ([tmpKey rangeOfString:param].location == NSNotFound)
{
[params setValue:param forKey:tmpKey];
tmpKey = nil;
}
tmpKey = param;
}
[tmpKey release];
return params;
}
It return Dictionary like it : Key = value
I edited Dimitris' code slightly for better memory management and efficiency. Also, it works in ARC.
URLParser.h
#interface URLParser : NSObject
- (void)setURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;
#end
URLParser.m
#import "URLParser.h"
#implementation URLParser {
NSMutableDictionary *_variablesDict;
}
- (void)setURLString:(NSString *)url {
[_variablesDict removeAllObjects];
NSString *string = url;
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *tempString;
[scanner scanUpToString:#"?" intoString:nil]; //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:#"&" intoString:&tempString]) {
NSString *dataString = [tempString copy];
NSArray *sepStrings = [dataString componentsSeparatedByString:#"="];
if ([sepStrings count] == 2) {
[_variablesDict setValue:sepStrings[1] forKeyPath:sepStrings[0]];
}
}
}
- (id)init
{
self = [super init];
if (self) {
_variablesDict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (NSString *)valueForVariable:(NSString *)varName {
NSString *val = [_variablesDict valueForKeyPath:varName];
return val;
return nil;
}
-(NSString *)description {
return [NSString stringWithFormat:#"Current Variables: %#", _variablesDict];
}
#end
Quickest is:
NSString* x = [url valueForQueryParameterKey:#"x"];

How to differentiate the returned value of a function using completion block in Objective C?

I have a function that gives 2 different String values that are returned :
-(NSString*)load:(NSDictionary *)dict
{
NSDictionary *dataDict = [self objectForId:#"data" fromDict:dict withDefault:nil];
if (dataDict) {
NSDictionary *success = [self objectForId:#"success" fromDict:dataDict withDefault:nil];
NSString *str = [NSString stringWithFormat:#"%#", success];
if ([str isEqualToString: #"1"])
{
NSDictionary *idDict = [self objectForId:#"id" fromDict:dataDict withDefault:nil];
if (idDict) {
NSString *idString = [NSString stringWithFormat:#"%#", idDict];
return idString;
}
} else {
NSDictionary *messages = [self objectForId:#"messages" fromDict:dataDict withDefault:nil];
if (messages) {
NSDictionary *messageDict = (NSDictionary *)messages;
NSArray *type = messageDict[#"type"];
if (type.count > 0) {
NSString *messageString = type[0][#"message"];
return messageString;
}
}
}
}
return nil;
}
And accessing the stringValue like this :
NSString *string = [className load:dict];
Now I want to write if else statements for "idString" and "messageString" return values. How do I differentiate the 2 return values?
While returning a NSDictionary (see #Yihui Yang solution), or a custom Class (see #Sulthan's solution) for it are valid solutions, it maybe be too much.
You need to remember the keys of the dictionary returned, or maybe creating a custom class just for that is too much.
Here are two other possibilities:
I'll have has sample dict to test:
NSDictionary *dictToTest1 = #{#"id": #"idString",
#"noiseKey": #"noiseValue"
};
NSDictionary *dictToTest2 = #{#"messages": #"messagesString",
#"noiseKey": #"noiseValue"
};
I'll simplify your test to check only if there is a key/value for key id or for messages.
Using Double pointers:
-(void)loadDict:(NSDictionary *)dict withRetKey:(NSString **)key andRetValue:(NSString **)value
{
NSString *retKey = nil;
NSString *retValue = nil;
if (dict[#"id"])
{
retKey = #"id";
retValue = dict[#"id"];
}
else if (dict[#"messages"])
{
retKey = #"messages";
retValue = dict[#"messages"];
}
if (key)
{
*key = retKey;
}
if (value)
{
*value = retValue;
}
}
Sample test:
NSString *key1 = nil;
NSString *value1 = nil;
[self loadDict:dictToTest1 withRetKey:&key1 andRetValue:&value1];
NSLog(#"Key1: %#\t value1: %#", key1, value1);
NSString *key2 = nil;
NSString *value2 = nil;
[self loadDict:dictToTest2 withRetKey:&key2 andRetValue:&value2];
NSLog(#"Key2: %#\t value2: %#", key2, value2);
Output:
$> Key1: id value1: idString
$> Key2: messages value2: messagesString
Where did you see the & for objects ?
Almost all the times in managing a NSError. (linked question)
For primitive? For sample if you want to retrieve the red/blue/green/alpha of a UIColor (linked question)
With blocks:
-(void)blockLoadDict:(NSDictionary *)dict withBlock:(void(^) (NSString *key, NSString *value))block
{
NSString *retKey = #"";
NSString *retValue = #"";
if (dict[#"id"])
{
retKey = #"id";
retValue = dict[#"id"];
}
else if (dict[#"messages"])
{
retKey = #"messages";
retValue = dict[#"messages"];
}
if (block)
{
block(retKey, retValue);
}
}
Sample:
__block NSString *key3 = nil;
__block NSString *value3 = nil;
[self blockLoadDict:dictToTest1 withBlock:^(NSString *key, NSString *value) {
key3 = key;
value3 = value;
}];
NSLog(#"Block Key3: %#\t value3: %#", key3, value3);
__block NSString *key4 = nil;
__block NSString *value4 = nil;
[self blockLoadDict:dictToTest2 withBlock:^(NSString *key, NSString *value) {
key4 = key;
value4 = value;
}];
NSLog(#"Block Key4: %#\t value4: %#", key4, value4);
Output:
$> Block Key3: id value3: idString
$> Block Key4: messages value4: messagesString
What I understand is that you want to know if load method returns an idString or messageString.
So what I recommend is using a tricky method.
Instead of return a string, you can return a dict which is like
return #{
#"type":#"idString",
#"content":idString
}
And using
NSDictionary * returnDict = [className load:dict]
if ([returnDict[#"type"] isEqualToString:#"idString"]) {
//code here
}
else{
//code here
}
Finally, I know this is not a best solution but it will work fine.
I'd make 2 separate methods. First would only return the id string, the second one would return a message.
That way you can make something like this:
NSDictionary *dict = /* some code here */;
NSString *message = nil;
NSString *idString = [foo loadId:dict];
if (idString.length == 0) {
message = [foo loadMessage:dict];
}
Instead of returning a simple string, create an object that will be returned:
#interface Result: NSObject
#property (nonatomic) NSString *id;
#property (nonatomic) NSString *message;
#end
Ideally, you could create -initWithDictionary: initializer that would handle the parsing.
You can use NSException. Instead of returning idString you throw an NSException
#throw [NSException exceptionWithName:idString reason:nil userInfo:nil];
Then you can call your method like this:
#try{
NSString *messageString = [className load:dict];
NSLog(#"Message String: %#", messageString);
}#catch (NSException *e){
NSString * idString = e.name;
NSLog(#"ID String: %#",idString);
}

"Can't allocate region" malloc error when running millions of iterations of loop

Thanks to a lot of help I've received here on SO, I've gotten an algorithm to check a list of around 15,000 8-letter words for any partial anagrams, against a list of around 50,000 total words (so I suppose a total of 108 million iterations). I call this method once for each comparison (so 750 million times). I'm getting the following error, always somewhere in the midst of the 119th iteration through the 1,350 there should be:
AnagramFINAL(2960,0xac8c7a28) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
I've narrowed the memory issue down to being a huge number of allocated CFStrings (immutable). Any idea what I can do to remedy the issue? I'm using ARC and an #autoreleasepool, not sure what else I could do, it seems something isn't being released when it should be.
AnagramDetector.h
#import <Foundation/Foundation.h>
#interface AnagramDetector : NSObject {
NSDictionary *allEightLetterWords;
NSDictionary *allWords;
NSFileManager *fileManager;
NSArray *paths;
NSString *documentsDirectory;
NSString *filePath;
}
- (BOOL) does: (NSString *) longWord contain: (NSString *) shortWord;
- (NSDictionary *) setupAllWordList;
- (NSDictionary *) setupEightLetterWordList;
- (void) saveDictionary: (NSMutableDictionary *)currentArray;
#end
AnagramDetector.m
#implementation AnagramDetector
- (id) init {
self = [super init];
if (self) {
fileManager = [NSFileManager defaultManager];
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
}
return self;
}
- (BOOL) does: (NSString *) longWord contain: (NSString *) shortWord {
#autoreleasepool {
NSMutableString *longerWord = [longWord mutableCopy];
for (int i = 0; i < [shortWord length]; i++) {
NSString *letter = [shortWord substringWithRange: NSMakeRange(i, 1)];
NSRange letterRange = [longerWord rangeOfString: letter];
if (letterRange.location != NSNotFound) {
[longerWord deleteCharactersInRange: letterRange];
} else {
return NO;
}
}
return YES;
}
}
- (NSDictionary *) setupAllWordList {
#autoreleasepool {
NSString *fileWithAllWords = [[NSBundle mainBundle] pathForResource:#"AllDefinedWords" ofType:#"plist"];
allWords = [[NSDictionary alloc] initWithContentsOfFile: fileWithAllWords];
NSLog(#"Total number of words: %d.", [allWords count]);
}
return allWords;
}
- (NSDictionary *) setupEightLetterWordList {
#autoreleasepool {
NSString *fileWithEightWords = [[NSBundle mainBundle] pathForResource:#"AllDefinedEights" ofType:#"plist"];
allEightLetterWords = [[NSDictionary alloc] initWithContentsOfFile: fileWithEightWords];
NSLog(#"Total number of words: %d.", [allEightLetterWords count]);
}
return allEightLetterWords;
}
- (void) saveDictionary: (NSMutableDictionary *)currentArray {
#autoreleasepool {
filePath = [documentsDirectory stringByAppendingPathComponent: #"A.plist"];
[fileManager createFileAtPath:filePath contents: nil attributes: nil];
[currentArray writeToFile: filePath atomically:YES];
[currentArray removeAllObjects];
}
}
#end
Code running on launch (inside AppDelegate for now, since no VC):
#autoreleasepool {
AnagramDetector *detector = [[AnagramDetector alloc] init];
NSDictionary *allWords = [[NSDictionary alloc] initWithDictionary:[detector setupAllWordList]];
NSDictionary *eightWords = [[NSDictionary alloc] initWithDictionary:[detector setupEightLetterWordList]];
int remaining = [eightWords count];
for (NSString *currentEightWord in eightWords) {
if (remaining % 10 == 0) NSLog(#"%d ::: REMAINING :::", remaining);
for (NSString *currentAllWord in allWords) {
if ([detector does: [eightWords objectForKey: currentEightWord] contain: [allWords objectForKey: currentAllWord]]) {
// NSLog(#"%# ::: CONTAINS ::: %#", [eightWords objectForKey: currentEightWord], [allWords objectForKey: currentAllWord]);
}
}
remaining--;
}
}
The problem seems to be that a lot of autoreleased objects fill up the memory waiting to be released. So a solution is to add your own autorelease pool scope to collect autoreleased objects and release them sooner.
I suggest that you do something like this:
for (NSString *currentEightLetterWord in [eightLetterWordsDictionary allKeys]) {
#autoreleasepool {
for (NSString *currentWord in [allWordsDictionary allKeys]) {
}
}
}
Now all autoreleased objects inside #autoreleasepool { .. } will be released for each iteration of the outer loop.
As you see ARC might save you from thinking about most reference counting and memory management issues but objects can still end up in autorelease pools with ARC when using methods that directly or indirectly create autoreleased objects.
An alternative solution that I don't really recommend is to try to avoid using method that will use autorelease. Then does:contain: could awkwardly be rewritten to something like this:
- (BOOL) does: (NSString* ) longWord contain: (NSString *) shortWord {
NSMutableString *haystack = [longWord mutableCopy];
NSMutableString *needle = [shortWord mutableCopy];
while([haystack length] > 0 && [needle length] > 0) {
NSMutableCharacterSet *set = [[NSMutableCharacterSet alloc] init];
[set addCharactersInRange:NSMakeRange([needle characterAtIndex:0], 1)];
if ([haystack rangeOfCharacterFromSet:set].location == NSNotFound) return NO;
haystack = [haystack mutableCopy];
[haystack deleteCharactersInRange:NSMakeRange(0, [haystack rangeOfCharacterFromSet: set].location)];
needle = [needle mutableCopy];
[needle deleteCharactersInRange:NSMakeRange(0, 1)];
}
return YES;
}

Refining description of NSDictionary

I want to see objects classes of my dictionary in console log. As for standard NSObject subclasses, I override -(NSString*) description in category:
-(NSString*) description
{
NSMutableString* desc = [NSMutableString stringWithFormat: #"<%# 0x%08x>\nobjects count: %ld", [self class], (uint)self, [self count]];
for (id key in [self allKeys])
[desc appendFormat: #"\n%# = %# (%#)", key, [self objectForKey: key], [[self objectForKey: key] class]];
return desc;
}
It works, but only for top-level NSDictionary object (if the object has dictionaries in children they are logged bypassing description method). So NSDictionary prints its children objects in some way without calling description on them...
Is there an approach to log these children dictionaries through my description method?
PS: In practical situation I want to find an object in dictionary that can't be saved to plist. Maybe there is another solution, I would be thankful for that too.
You can write a recursive description method:
// Private Methods
#interface MyClass ()
- (NSString *)_description:(id)object;
#end
...
- (NSString *)_description:(id)object
{
if ([object isKindOfClass:[NSDictionary class]])
{
NSDictionary *dict = (NSDictionary *)object;
NSMutableString *desc = [NSMutableString stringWithFormat: #"<%# %p>\nobjects count: %ld", [dict class], dict, [dict count]];
for (id key in [dict allKeys])
{
[desc appendFormat: #"\n%# = %# (%#)", key, [self _description:[objectForKey: key]], [[self objectForKey: key] class]];
return desc;
}
}
else
{
return [(NSObject *)object description];
}
}
- (NSString *)description
{
return [self _description:self];
}
You'll probably want to pass an incrementing indentation counter so you can format the child objects better, but you should get the idea.

CS193P - Assignment 2, descriptionOfTopOfStack:, recursive class method

below is a class method that always returns null -when, for example, stack = 2,2,"+" I want it to return "2+2"
In the initial iteration the method correctly determines the topOfStack is a NSString rather than a NSNumber but is doesn't create NSString 'description' to equal "2+2" by recursive calling
I feel I'm missing something obvious here, am I dealing with the strings correctly....
+ (NSString *) descriptionOfTopOfStack: (NSMutableArray * ) stack
{
NSString *description;
id topOfStack = [stack lastObject]; // get last object
if (topOfStack) [stack removeLastObject]; // then remove it from stack
if ([topOfStack isKindOfClass:[NSNumber class]]) { // is last object a number?
return [topOfStack stringValue]; // if so then return it, **done***
}
else if ([topOfStack isKindOfClass:[NSString class]])
{
if ([topOfStack isEqualToString:#"+"])
{
[description stringByAppendingString: [self descriptionOfTopOfStack:stack]];
[description stringByAppendingString:#"+"];
[description stringByAppendingString: [self descriptionOfTopOfStack:stack]];
}
}
NSLog(#"Description is %#", description);
return description;
}
Method stringByAppendingString: returns an autoreleased string, does not modify the original one. If you want to modify description you must do something like
description = [description stringByAppendingString: [self descriptionOfTopOfStack:stack]];
Besides, writing
NSString *description;
you are just creating a pointer to a NSString, not a NSString. Use instead
NSString* description = #"";