2

私はAFNetworkingWebリクエストを行うために使用しています。Web リクエストが完了した後。UIAlertView を表示したい。私は ARC を使用していますが、コードはデバイス上で動作するようです。シミュレーターを使用すると、次のエラーが表示されます: EXC_BAD_ACCESS

私は何を間違っていますか?

UIAlertView* postSubmitAlertView = [[UIAlertView alloc] init];
postSubmitAlertView.delegate = self;
[postSubmitAlertView addButtonWithTitle:@"Ok"];

AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] 
    initWithRequest:request];

[op setCompletionBlock:^(void) {
    if(op.response.statusCode == 200) {

        postSubmitAlertView.title = @"Submission Good";
        postSubmitAlertView.message = @"GOOD";

   } else {

        postSubmitAlertView.title = @"Submission Failed.";
        postSubmitAlertView.message = @"FAIL";
   }

   [postSubmitAlertView show];
}];
[op start];
4

3 に答える 3

4

主な問題はUIKit、メイン スレッドでスタッフを呼び出す必要があることです。

注:ほとんどの場合、UIKit クラスはアプリケーションのメイン スレッドからのみ使用する必要があります。これは特に、UIResponder から派生したクラス、または何らかの方法でアプリケーションのユーザー インターフェイスを操作することを伴うクラスに当てはまります。

UIKit フレームワーク リファレンス

下のNSOperationのドキュメントを見るsetCompletionBlock:

ディスカッション 完了ブロックの正確な実行コンテキストは保証されていませんが、通常はセカンダリ スレッドです。したがって、このブロックを使用して、非常に特殊な実行コンテキストを必要とする作業を行うべきではありません。代わりに、その作業をアプリケーションのメイン スレッドまたはそれを実行できる特定のスレッドにシャントする必要があります。

コードを変更する最も簡単な解決策はUIKit、メインスレッドでものを呼び出すことです

- (void)viewDidLoad
{
  [super viewDidLoad];

  NSURL *URL = [NSURL URLWithString:@"http://www.google.com"];
  NSURLRequest *request = [NSURLRequest requestWithURL:URL];

  AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc]
                                initWithRequest:request];

  [op setCompletionBlock:^(void) {

    dispatch_async(dispatch_get_main_queue(), ^{
      UIAlertView* postSubmitAlertView = [[UIAlertView alloc] init];
      postSubmitAlertView.delegate = self;
      [postSubmitAlertView addButtonWithTitle:@"Ok"];

      if(op.response.statusCode == 200) {

        postSubmitAlertView.title = @"Submission Good";
        postSubmitAlertView.message = @"GOOD";

      } else {

        postSubmitAlertView.title = @"Submission Failed.";
        postSubmitAlertView.message = @"FAIL";

      }

      [postSubmitAlertView show];
    });

  }];
  [op start];
}
于 2012-10-05T21:08:18.840 に答える
1

EXC_BAD_ACCESS は、解放されたオブジェクトにアクセスすることによって発生します。これを避けるには、UIAlertView の呼び出しをモーダルにします。

//Function body:

-(void)checkSaving
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Do you want to add these results to your database?"
                                                    message:@"\n\n"
                                                   delegate:self
                                          cancelButtonTitle:@"No"
                                          otherButtonTitles:@"Save", nil];
    alert.alertViewStyle = UIAlertViewStyleDefault;
    [alert show];

    //this prevent the ARC to clean up :
    NSRunLoop *rl = [NSRunLoop currentRunLoop];
    NSDate *d;
    d = (NSDate*)[d init];
    while ([alert isVisible]) {
        [rl runUntilDate:d];
    }
}

//Your choice result:

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    // the user clicked one of the OK/Cancel buttons
    if (buttonIndex == 1)//Save
    {
        //do something    
    }
    if (buttonIndex == 0)//NO
    {
        //do something
    }
}

//Register the functions in the interface declaration:

@interface yourViewController ()
-(void)checkSaving
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
//...
@end


//To call:

[self checkSaving];

これがお役に立てば幸いです。

于 2012-12-08T13:01:16.237 に答える
0
UIAlertView* postSubmitAlertView = [[UIAlertView alloc] init];
postSubmitAlertView.delegate = self;
[postSubmitAlertView addButtonWithTitle:@"Ok"];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
[operation  setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSLog(@"success: %@", operation.responseString);   
        postSubmitAlertView.title = @"Submission Good";
        postSubmitAlertView.message = @"GOOD";

} 
    failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"error: %@",  operation.responseString);
        postSubmitAlertView.title = @"Submission Failed.";
        postSubmitAlertView.message = @"FAIL";

}
 ];

[postSubmitAlertView show];

これで問題が解決することを願っています。

于 2012-10-05T21:03:33.707 に答える