Reputation: 2058
I have the following code:
.h
NSString *mainString;
.m
case 0:
case 1:
case 2:
if ([typeTo textAlignment] == UITextAlignmentRight) {
typeTo.text = [NSString stringWithFormat:@""];
mainString = @"";
[typeTo setTextAlignment:UITextAlignmentLeft];
typeTo.text = [NSString stringWithFormat:@"%@%d", typeTo.text, [sender tag]];
mainString = [NSString stringWithFormat:@"%@%d", mainString, [sender tag]];
} else {
typeTo.text = [NSString stringWithFormat:@"%@%d", typeTo.text, [sender tag]];
mainString = [NSString stringWithFormat:@"%@%d", mainString, [sender tag]];
}
NSLog(@"%@",mainString);
break;
Crashes on this line usually.
mainString = [NSString stringWithFormat:@"%@%d", mainString, [sender tag]];
Code works one then crashes.
both typeTo.text
and mainString
start as @""
And text alignment starts left.
What am I doing wrong?
Upvotes: 0
Views: 1006
Reputation: 92336
If you are not using ARC, then you need to either retain the created string or create it with alloc
. So either:
mainString = [[NSString stringWithFormat:@"%@%d", mainString, [sender tag]] retain];
or better yet:
mainString = [[NSString alloc] initWithFormat:@"%@%d", mainString, [sender tag]];
This of course means you also need to release
it before assigning a new value.
The reason for the crash is likely because you assign the autorelease instance to the pointer, then the object gets autoreleased but the pointer still points to that now-dead object.
Another way would be to use a property with retain
or copy
keyword. For strings, copy
is usually the better solution because you could accidentally pass a NSMutableString
and then later modify it.
Edit to answer comments:
In this case, to avoid a memory leak, the following should be done:
[mainString autorelease];
mainString = [[NSString alloc] initWithFormat:@"%@%d", mainString, [sender tag]];
The reason why this is necessary is because the mainString
is used as an argument to create a new object, which is then in turn assigned to mainString
. So before the initWithFormat:
line, mainString
pointed to a string object A. After that line, it now points to a new string object B. But you need to make sure to clean up A, which is why the autorelease is necessary. If you don't you'd have a memory leak and eventually your app will run out of memory.
Alternatively, you could also do:
NSString *tmp = mainString;
mainString = [[NSString alloc] initWithFormat:@"%@%d", tmp, [sender tag]];
[tmp release];
The difference is that autorelease
says: I need this object for a short while, but some time after I leave this method it must be cleaned up if possible. release
says: I don't need the object any more, please clean it up now if possible.
Upvotes: 2