タイトルが少し変に聞こえるかもしれませんが、同じことが問題にも当てはまります。
私は開発中のほぼすべての時間、シミュレーターでアプリをテストしてきました。念のため、実際のデバイスで時々テストしました。しかし、問題が終わりに近づいた今、問題が発生しました。
ログインを実行するたびに、アプリ全体がクラッシュし、ユーザー名とパスワードの変数の割り当てが解除されます...
これが私のアプリケーションの流れです:
アプリを開くと、ユーザー名とパスワードが保存されているかどうかを確認するか、メモします
- (void)checkIfPreviouslyLoggedIn:(BOOL)didLogin andLogin:(BOOL)doLogin {
// some logic to get it out of the keychain
NSLog(@"checkIfPreviouslyLggedIn: ACCOUNT %@ / %@", tmpUsername, tmpPassword);
// RETURN: checkIfPreviouslyLggedIn: ACCOUNT /
}
以前は何も保存されていませんでした。大したことではありません。ユーザーはアカウントを入力してログインを押すだけです。
- (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"];
}
かっこいい、ユーザー名とパスワードはうまく記録されています。これまでのところ、doRequestFromLocationは基本的にキュータイプのものであり、必要な数のリクエストを送信でき、それらを1つずつ処理します。
- (void)doRequestFromLocation:(NSString *)location withPostType:(NSString *)type andData:(NSData *)data whichTriggersNotification:(NSString *)notification {
NSLog(@"doRequestFromLocation: ACCOUNT %@ / %@", _username, _password);
// RETURN: doRequestFromLocation: ACCOUNT testUser / password
}
次に、実際のデータ要求を行うdoRequestメソッドに移動します。ここでも、ユーザー名をログに記録すると、正しいユーザー名が返されます。
NSLog(@"doRequest: ACCOUNT %@ / %@", _username, _password);
この後、すべてがひどく悪くなります。リクエストが完了すると、loginCheck()が呼び出されます。
- (void)loginCheck:(NSNotification *)notification {
NSLog(@"loginCheck: ACCOUNT %@ / %@", _username, _password);
}
ここでは、_usernameと_passwordの割り当てが解除されています。実際の呼び出しの直前でも、ユーザー名とパスワードを確認しましたが、問題はありません。
したがって、どういうわけか(魔法のように)これらの2つの変数は理由もなく割り当てが解除されました。_usernameと_passwordはloginWithUsernameでのみ設定され、アプリケーションのどこでも変更されないことに注意してください。
2012-06-04 13:33:28.001 coop [5060:707] *-[CFString replysToSelector:]:割り当て解除されたインスタンスに送信されたメッセージ0x1099fc40 2012-06-04 13:33:28.648 coop [5060:707] * -[CFString _cfTypeID]:割り当て解除されたインスタンス0x1099fc40に送信されたメッセージ
これを引き起こした可能性があるのは、複数のブレークポイントを追加したことですが、呼び出しとloginCheck()の間のどこかでブレークポイントが消えることに気づきました。