UIAlertView出现较晚

时间:2013-08-30 11:10:44

标签: iphone ios web-services uialertview

我在ios应用程序中与服务器通信。我有以下方法,我打开一个alertview。我想在应用程序从服务器获得响应时显示加载视图。

- (void) showDetailedQuestion:(id)sender
{
       //loading view                  
        self.loading_alert = [[UIAlertView alloc] initWithTitle:@"Loading\nPlease Wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
        [self.loading_alert show];

        UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

        // Adjust the indicator so it is up a few pixels from the bottom of the alert
        indicator.center = CGPointMake(loading_alert.bounds.size.width / 2, loading_alert.bounds.size.height - 50);
        [indicator startAnimating];
        [self.loading_alert addSubview:indicator];

    UIButton *btn = (UIButton*)sender;
    int indx = btn.tag;

    NSLog(@"tag:%d",indx);
    answerAnQuestion *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"Answer"];

    vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal ;
    vc.que_id = [self.que_id valueForKey:[NSString stringWithFormat:@"%d",indx]];
    vc.qid_list = self.que_id;
    vc.crnt = indx;

    [self presentViewController:vc animated:YES completion:nil];
    [self.loading_alert dismissWithClickedButtonIndex:0 animated:YES];
}

和另一个答案AnQuestion.m

- (void)viewDidLoad
{
            NSString *address = [NSString stringWithFormat:@"%@%@%@%@%@%@%@", path,@"questions/",que_id,@"?token=",token,@"&user_id=",usrId];
    NSURL *URL = [NSURL URLWithString:address];
    NSLog(@"%@",address);

    [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[URL host]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLCacheStorageAllowedInMemoryOnly
                                                       timeoutInterval:60.0];
    [request setHTTPMethod:@"GET"];
    responseData = [[NSMutableData alloc] init];

    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

    if (data) 
    {
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
        //If you need the response, you can use it here
        int statuscode = [httpResponse statusCode];
        NSString *responseMsg = [NSHTTPURLResponse localizedStringForStatusCode:statuscode];
        NSLog(@" Status code: %d",statuscode );
        NSLog(@" Status msg: %@",responseMsg );

    }
    else 
    {
        // Handle error by looking at response and/or error values
        NSLog(@"%@",error);
    }
}

我的问题是alertview仅在视图发生变化时出现。它假设在我点击按钮时打开。可能是什么原因?怎么解决这个?

编辑1:

如果我向服务器发出异步请求,那么我无法在tableview中设置这些数据。我可以在tableview中设置这些数据仅在发送同步请求时,但它会阻止应用程序。为什么会这样?

任何帮助将不胜感激。 谢谢。

2 个答案:

答案 0 :(得分:1)

您正在主线程上发送SynchronousRequest,因此它阻止了您的UI线程。阅读多线程,您将获得有关此的各种教程。我建议你去GCD或NSOperation和NSOperationQueue。对于上述任何一种情况的谷歌,您将获得相同的样本。

或者您可以按如下方式发送异步请求...

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
        //Write code you want to call when data is received,
        //Like dismissing loading view and populating UI.
 }];

更新:

//Display alert view, before sending your request..
[alertview show];
//send first request
[NSURLConnection sendAsynchronousRequest:request1 queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){

            //Write code you want to call when data is received,
            //send second request
[NSURLConnection sendAsynchronousRequest:request2 queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){

            //Write code you want to call when data is received,
            //send third request
[NSURLConnection sendAsynchronousRequest:request3 queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
            //Write code you want to call when data is received,
            //dismiss alert view on main thread
dispatch_async(getmainqueue, ^(void) { 
// dismiss alert view... 
});
     }];
     }];

     }];

答案 1 :(得分:0)

我使用过Nuzhat Zari代码,我感谢他,但是在嵌套的“sendAsynchronousRequest”(得到一些奇怪的线程和内存错误)之间也经历了一些核心数据操作的问题所以,我的解决方案是不需要的调用“sendAsynchronousRequest”并使用一些主线程变量验证。

@interface myMainThreadClass
@property (nonatomic,assign) NSInteger *currentAsyncTasks;
@end
@implementation

// Use init or viewDidLoad to make "currentAsyncTasks=0"!!

-(void)method
{
[self showLoadingAlert]; //or some ui update function

currentAsyncTasks++;
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
    //do something with data
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        [self dismissAlertInFinalTask] 
    });
}];
 currentAsyncTasks++;
[NSURLConnection sendAsynchronousRequest:urlRequest2 queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
    //do something with data 
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        [self dismissAlertInFinalTask] 
    });
}];

 currentAsyncTasks++;
[NSURLConnection sendAsynchronousRequest:urlRequest3 queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){

   //do something with data 
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        [self dismissAlertInFinalTask] 
    });
}];
}
-(void)dismissAlertInFinalTask
{
    currentNetworkTasks--;
    if (currentNetworkTasks == 0)
    {
        [self dismissLoadingAlert];//or some ui update function;
    }
}
@end

我还想知道是否有人使用NSURLConnection委托NSURLConnectionDataDelegate和ui调用设法做多个请求。