0

I can't belice I am asking this, but im very crazy with this variable stuff.

I want to save a username information. I load them at the load of my view. After this I will get the information when I click on a button.

Here is my code:

@interface SelfViewController : UIViewController
{
    NSString *usernameString;
}



- (void)viewDidLoad
{
     usernameString = @"test";
}



- (IBAction)goToProfileButtonPressed:(id)sender
{
    NSLog(@"%@", usernameString); //CRASH BAD EXEC

}

What did I wrong????

PassionateDeveloper
  • 14,558
  • 34
  • 107
  • 176
  • you should synthesize you iVar and generate a property. you get a BAD EXEC error because you doenst retain the autoreleased NSString @"test" – CarlJ Apr 11 '12 at 14:23
  • There is nothing wrong with that code other than its not a complete minimal example. You should also state if you are using ARC or not. – Joe Apr 11 '12 at 14:23
  • My first guess is that the button isn't properly connected to an instance of SelfViewController. If you remove the `NSLog`, can you press the button without causing a crash? – Cowirrie Apr 11 '12 at 14:25
  • @Dondragmer: Yes, without problems. – PassionateDeveloper Apr 11 '12 at 14:29
  • If you include `NSLog(@"Text");` - without trying to display `usernameString` - does that appear? – Cowirrie Apr 11 '12 at 14:31
  • Now I'm curious... can you `NSLog(@"%@", usernameString);` immediately after you assign it, in `viewDidLoad`? – Cowirrie Apr 11 '12 at 14:40
  • Note to some of answerers of this question - Just because you have an instance variable does not mean you need to create a property for it. For @Kovu - 1) You did not state if you are using ARC or not, this is important for memory related issues. 2) This is not a complete minimal example (this won't compile as is so I am sure you have other code..) 3) Try running zombies if you get the issue with something other than a string literal. – Joe Apr 11 '12 at 14:49

2 Answers2

1

Change your .h file to:

@interface SelfViewController : UIViewController {
    NSString *usernameString;
}

@property (retain, nonatomic) NSString *usernameString;

Then in your .m file:

@synthesize usernameString;

- (void)viewDidLoad {
     self.usernameString = @"test";
}

- (IBAction)goToProfileButtonPressed:(id)sender {
    NSLog(@"%@", self.usernameString); // "self." can be omitted, but it is best practice not to
}

- (void)dealloc {
    [usernameString release];

    [super dealloc];
}

The problem is that you assign usernameString to an autoreleased string object. By the time the button is pressed, usernameString has been released and has become garbage memory. By retaining it (and subsequently releasing it in -dealloc to avoid a leak) you know that it will not be prematurely released.

jrtc27
  • 8,496
  • 3
  • 36
  • 68
  • The Self was the problem. Thanks – PassionateDeveloper Apr 11 '12 at 14:47
  • No problem - the `self` means that instead of directly setting the variable, it performs actions based on the property type. As we have set it to retain (and nonatomic, which just means it is thread-unsafe but faster), by using `self` it is retained. Hope this makes sense! – jrtc27 Apr 11 '12 at 14:51
  • Just a minor terminology correction: "The problem is that you assign usernameString to an autoreleased string object" <- actually no, string constants are *not* autoreleased and *not* get released when returning from a method. However, upon end-of-scope, they do get purged from memory. Same thing that happens to stack-allocated local arrays. –  Apr 11 '12 at 15:03
0

You need to synthesize the ivar and add it as a property. (For not-ARC compiling):

in the .h:

@interface SelfViewController : UIViewController
{
    NSString *usernameString;
}    
@property (nonatomic, retain) NSString *usernameString;

in the .m:

@synthesize usernameString;