0

最近、MDProgressHUD をアプリに追加し、ReadMe ドキュメントの指示に従って、HUD をメイン キューにセットアップし、新しいスレッドで他のタスクを実行するようにアドバイスしました。これが実装方法です。アプリの最初の起動時にすべて正常に動作しますが、電話のホームボタンを選択してアプリをバックグラウンドに配置し、アプリのアイコンを選択してフォアグラウンドに復元すると、アプリがクラッシュします.

私は次のようにコードを実装しました。ユーザーが [OK] ボタンを選択すると、アプリは Web サービス (NSURLConnection)、つまり authenticateUser を呼び出してログイン ID とパスワードを認証します。

- (IBAction)Ok:(id)sender {

    [self.txtPassword resignFirstResponder];

    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
       [self authenticateUser];
       [MBProgressHUD hideHUDForView:self.view animated:YES];
    });

}

- (void)authenticateUser {

   self.loginEmailAddress = self.txtEmailAddress.text;
   self.loginPassword = self.txtPassword.text;

   if ([self.loginEmailAddress isEqualToString:@""] || [self.loginPassword isEqualToString:@""]) {
    self.lblErrMsg.text = @"Invalid login details. Please try again.";
    self.lblErrMsg.hidden = NO;
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    return;
}


    NSString *myRequestString = [NSString stringWithFormat:@"org_id=%@&login_id=%@&pword=%@", signedUpOrgId, self.loginEmailAddress, self.loginPassword];
    NSString *myEncodedRequestString = [myRequestString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

    NSData *myRequestData = [myEncodedRequestString dataUsingEncoding:NSUTF8StringEncoding];

    NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:serviceURL
                                                      cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                    timeoutInterval:60.0];


    [theRequest setHTTPMethod: @"POST"];
    [theRequest setHTTPBody: myRequestData];

    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

    if (theConnection) {
        receivedData = [NSMutableData data];

    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorry! Can't connect." message:@"Sorry, but there seems to be a problem connecting to the internet at the moment. Please try again or wait until you have better reception for a data connection." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [alert show];
    }
}

ログ:

2012-07-17 23:40:33.699 AppName[6155:707] -[ContactListViewController authenticateUser]: unrecognized selector sent to instance 0x2616e0
2012-07-17 23:40:33.704 AppName[6155:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ContactListViewController authenticateUser]: unrecognized selector sent to instance 0x2616e0'
*** First throw call stack:
(0x3146588f 0x377a3259 0x31468a9b 0x31467915 0x313c2650 0x31d78933 0x31439a33 0x31439699 0x3143826f 0x313bb4a5 0x313bb36d 0x33435439 0x30b1ecd5 0xe13c7 0xe136c)
terminate called throwing an exception

アプリが 2 回目にクラッシュする理由がわかりません。どんな援助でも大歓迎です。

4

1 に答える 1

0

ブロック内で参照selfする場合は、「弱い」変数を介して間接的に参照することをお勧めします (そうしないと、適切に割り当てが解除されない可能性があります)。

__weak ContactListViewController *weakself = self; dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [weakself authenticateUser]; [MBProgressHUD hideHUDForView:weakself.view animation:YES]; });

これは、あなたへの参照がそのブロックにバインドされているためです。そして、それには重要な意味があります。このブロックがあなたに適切な参照を与えるのに十分な時間ぶらぶらしていると確信していますか? それを熟考し、それが呼び出されたときのオブジェクトがself、このブロックの実行で有効なインスタンスであるのに十分な時間、他の誰かに「属している」ことを確認する必要がある場合があります。

于 2012-07-17T14:46:25.883 に答える