Search code examples
iosdealloc

Variable suddenly removed


I know the title may sound a little weird, but the same goes for the problem.

I've been testing my app on the simulator almost the entire time in development, I did test it once in a while on a real device just to make sure. But now that I'm close to finishing a problem came up.

Whenever I preform a login, my entire app crashes saying the username and password variables are deallocated ...

Here's the flow of my application:

When opening the app, it checks if the username and password was saved or note

- (void)checkIfPreviouslyLoggedIn:(BOOL)didLogin andLogin:(BOOL)doLogin {
     // some logic to get it out of the keychain
     NSLog(@"checkIfPreviouslyLggedIn: ACCOUNT %@ / %@", tmpUsername, tmpPassword);

     // RETURN: checkIfPreviouslyLggedIn: ACCOUNT  /
}

Nothing was saved before, no big deal, the user will just input the account and press login

- (void)loginWithUsername:(NSString *)username andPassword:(NSString *)password {
      NSLog(@"loginWithUsername: ACCOUNT %@ / %@", username, password);
      // RETURN: loginWithUsername: ACCOUNT testUser / password

      // save it for later use
      _username = username;
      _password = password;

      NSLog(@"loginWithUsername: ACCOUNT %@ / %@", _username, _password);
      // RETURN: loginWithUsername: ACCOUNT testUser / password

      // Attach a notification handler
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginCheck:) name:@"LoginCheck" object:nil];

      // call the web API
      [self doRequestFromLocation:@"/groups" withPostType:@"GET" andData:nil whichTriggersNotification:@"LoginCheck"];
}

Cool, the username and password are nicely logged, so far so good, the doRequestFromLocation is basically a queue type thing, I can send as many requests as I want and it will handle them one by one

- (void)doRequestFromLocation:(NSString *)location withPostType:(NSString *)type andData:(NSData *)data whichTriggersNotification:(NSString *)notification {
      NSLog(@"doRequestFromLocation: ACCOUNT %@ / %@", _username, _password);
      // RETURN: doRequestFromLocation: ACCOUNT testUser / password
} 

It then goes to a doRequest method, which does the actual data request, again, I log my username there and it's returning the correct one.

NSLog(@"doRequest: ACCOUNT %@ / %@", _username, _password);

It's after this that everything goes horribly wrong, when the request is completed, loginCheck() is called

- (void)loginCheck:(NSNotification *)notification {
    NSLog(@"loginCheck: ACCOUNT %@ / %@", _username, _password);
}

In here my _username and _password are deallocated, even right before the actual call I check the username and password and they are still fine.

So somehow (magically) those 2 variables got deallocated without any reason. Note that _username and _password is ONLY set in loginWithUsername, they don't change anywhere in my application.

2012-06-04 13:33:28.001 coop[5060:707] * -[CFString respondsToSelector:]: message sent to deallocated instance 0x1099fc40 2012-06-04 13:33:28.648 coop[5060:707] * -[CFString _cfTypeID]: message sent to deallocated instance 0x1099fc40

What could have caused this, I added multiple breakpoints, only to realize that somewhere between the call and the loginCheck() they disappear.


Solution

  • the problem is here:

     // save it for later use
          _username = username;
          _password = password;
    

    your variables _username and _password are not retained that's why they are getting autoreleased.

    either in NON-ARC case, declare them as @property(retain) and for ARC, @property(strong) use :

    self._username = username;
    self._password = password;
    

    now you own the ownership of the memory and now you have to release it whenever you're done.