如何冻结我的应用以等待回复?

时间:2016-03-02 07:31:36

标签: ios objective-c thread-safety objective-c-blocks

我有一个简单的应用程序尝试登录用户。

用户插入用户名和密码 我在另一个类中调用了一个方法 - >

if ([myBankLogger checkUserLogin:self.memberNumber.text :self.accessCode.text])
{
        //Check if user credential is correct
        NSLog(@"Corrct");
}
else
{
        NSLog(@"Not correct");
}

checkUserLogin中,我向服务器发送http请求,并且需要一分钟才能得到响应:

-(bool) checkUserLogin :(NSString*)username :(NSString*)password
{

    __block bool tmp= false;
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager POST:string parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) {

        NSLog(@"JSON: %@", responseObject);
        if (responseObject[@"secret_token"])
        {
            NSLog(@"HERE");
            tmp = true;
        }

    } failure:^(NSURLSessionTask *operation, NSError *error) {
        NSLog(@"Error: %@", error);
        tmp = false;
    }];

    return tmp;
}

由于正常的编译器剂量不等到它完成处理。它返回false。我研究并发现我必须使用它:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
    // Perform async operation
    // Call your method/function here
    // Example:
    // NSString *result = [anObject calculateSomething];
    dispatch_sync(dispatch_get_main_queue(), ^{
        // Update UI
        // Example:
        // self.myLabel.text = result;
    });
});

但我不知道我应该把代码放在哪里?感谢任何建议或更简单的解决方案。

1 个答案:

答案 0 :(得分:0)

If you perform a synchronous operation on the main thread, this will block the app UI for the entire duration of that sync operation. If it takes too much, the OS will kill the application execution. With an async approach using the dispatch method, you can solve the UI blocking problem:

[self.myRingLoading startAnimating]; // show a ring loading while the following long operation will take (here you are in the main thread scope)

// this dispatch block will move all the actions in an async thread, avoiding any UI blocking issue
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

    // Perform here your UI blocking operation
    // sample blocking ui operation 
    NSData* httpDataResult = [NSData dataWithContentsOfURL:@"http://api.yoursite.com/xyz"];
    NSString* httpStringResult = [[NSString alloc] initWithData:httpDataResult  encoding:NSUTF8StringEncoding];

    // this dispatch block will send all action execution to the main queue, commonly the main thread
    dispatch_async(dispatch_get_main_queue(), ^(void){
        // Perform your UI operation (eg: printing the http response received by the server
        [self.myUILabel setText:httpStringResult];
        [self.myRingLoading stopAnimating]; // hide the ring loading since the long operation is finished
    });
});

There are other native solutions for obtaining the result, for example using the NSOperation and NSOperationQueue. If you use AFNetworking, you can take advantage of several good implementations, for example AFHTTPRequestOperation:

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

    // Perform your UI actions for the Success case

} 
    failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    // Perform your UI actions for the Failed case

}
 ];
// run the http operation process
[operation start];

Hope it helps