So here is my scenario -- In the header file of a class I do:
@interface MyClass : NSObject
{
NSString *string1;
NSString *string2;
}
- (void) methodOne: (NSString *) passedString;
- (void) methodTwo: (NSString *) passedString;
@end
In the implementation file I do this:
#import MyClass.h
@implementation MyClass
- (void) methodOne: (NSString *) passedString
{
NSLog(@"%@", passedString);
string1 = passedString;
}
- (void) methodTwo: (NSString *) passedString
{
NSLog(@"%@", passedString);
string2 = passedString;
}
What I am finding is that there is some kind of inconsistency when doing this versus [NSString alloc] initWithString:].
As you can see string1 and string2 are treated exactly the same, but what is happening is that string1 is getting set, but string2 is remaining empty. I get a bad access when I reference it later.
I thought maybe I was passing an empty string to methodTwo: so I added that NSLog which proves that it is not empty, but has the expected string.
Since I have noticed this inconsistency before I decided to change to this:
- (void) methodOne: (NSString *) passedString
{
NSLog(@"%@", passedString);
string1 = passedString;
}
- (void) methodTwo: (NSString *) passedString
{
NSLog(@"%@", passedString);
string2 = [[NSString alloc] initWithString: passedString];
}
Now both strings are working as expected. My question is why is there this inconsistency?
This is not the only time this has happened to me. It has happened with all kinds of objects. The only thing that seems to work every time is alloc init. Methods like stringWithString: work most of the time, but not always.
It's because in the first example, you don't retain or copy the strings. string2 is getting deallocated at some point before you use it. It's actually pure luck that string1 is OK. You should change your code to be something like this:
- (void) methodOne: (NSString *) passedString
{
NSLog(@"%@", passedString);
NSString* oldString = string1;
string1 = [passedString copy];
[oldString release];
}
- (void) methodTwo: (NSString *) passedString
{
NSLog(@"%@", passedString);
NSString* oldString = string2;
string2 = [passedString copy];
[oldString release];
}
and release in dealloc
-(void) dealloc
{
[string1 release];
[string2 release];
// other stuff
[super dealloc];
}
I strongly recommedn you create properties for string1 and string2 to handle all that reference counting stuff:
@interface MyClass : NSObject
{
NSString *string1;
NSString *string2;
}
- (void) methodOne: (NSString *) passedString;
- (void) methodTwo: (NSString *) passedString;
@property (copy) NSString* string1;
@property (copy) NSString* string2;
@end
@imlementation MyClasss
@synthesize string1, string2;
- (void) methodOne: (NSString *) passedString
{
NSLog(@"%@", passedString);
[self setString1: passedString];
}
- (void) methodTwo: (NSString *) passedString
{
NSLog(@"%@", passedString);
[self setString2: passedString];
}
// dealloc as before
@end