0

タイトルが少し変に聞こえるかもしれませんが、同じことが問題にも当てはまります。

私は開発中のほぼすべての時間、シミュレーターでアプリをテストしてきました。念のため、実際のデバイスで時々テストしました。しかし、問題が終わりに近づいた今、問題が発生しました。

ログインを実行するたびに、アプリ全体がクラッシュし、ユーザー名とパスワードの変数の割り当てが解除されます...

これが私のアプリケーションの流れです:

アプリを開くと、ユーザー名とパスワードが保存されているかどうかを確認するか、メモします

- (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()の間のどこかでブレークポイントが消えることに気づきました。

4

2 に答える 2

1

ヘッダー ファイルでプロパティ (_username と _password) をどのように宣言したかを確認してください。として宣言されていない場合

@property (nonatomic, retain) NSString * _username;
@property (nonatomic, retain) NSString * _password;

その後、プロパティは自動解放されます。そのため、後でこのプロパティにアクセスしようとすると、割り当てが解除されたというメッセージが表示されます。

また、ヘッダー ファイルで変数をプロパティとして宣言する場合は、"self." でアクセスしてください。

プロパティの割り当てを解除するのは、それらの処理が完了してからにしてください。このプロパティにそれ以上アクセスする必要はありません。

同じことについてさらに助けが必要な場合はお知らせください

于 2012-06-04T05:56:13.167 に答える
1

問題はここにあります:

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

あなたの変数は保持され_username_passwordいないため、自動解放されています。

非ARCの場合は、ARCとして宣言し、ARC@property(retain)の場合は次を@property(strong)使用します。

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

これで、メモリの所有権を所有し、完了したらいつでも解放する必要があります。

于 2012-06-04T05:46:48.953 に答える