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.
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.