gpt4 book ai didi

ios - 使用信号量从异步调用返回值

转载 作者:可可西里 更新时间:2023-11-01 17:15:46 24 4
gpt4 key购买 nike

我需要使用 NSURLSession 进行网络调用。基于某些事情,我收到响应后,需要返回一个NSError对象。

我正在使用信号量使异步调用同步运行。问题是,err 在调用中正确设置,但是一旦信号量结束(在

dispatch_semaphore_wait(信号量,DISPATCH_TIME_FOREVER);

),err 变为 nil。

请帮忙

代码:

-(NSError*)loginWithEmail:(NSString*)email Password:(NSString*)password
{
NSError __block *err = NULL;

// preparing the URL of login
NSURL *Url = [NSURL URLWithString:urlString];

NSData *PostData = [Post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

// preparing the request object
NSMutableURLRequest *Request = [[NSMutableURLRequest alloc] init];
[Request setURL:Url];
[Request setHTTPMethod:@"POST"];
[Request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[Request setHTTPBody:PostData];

NSMutableDictionary __block *parsedData = NULL; // holds the data after it is parsed

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.TLSMinimumSupportedProtocol = kTLSProtocol11;

NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];

NSURLSessionDataTask *task = [session dataTaskWithRequest:Request completionHandler:^(NSData *data, NSURLResponse *response1, NSError *err){
if(!data)
{
err = [NSError errorWithDomain:@"Connection Timeout" code:200 userInfo:nil];
}
else
{
NSString *formattedData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"%@", formattedData);

if([formattedData rangeOfString:@"<!DOCTYPE"].location != NSNotFound || [formattedData rangeOfString:@"<html"].location != NSNotFound)
{
loginSuccessful = NO;
//*errorr = [NSError errorWithDomain:@"Server Issue" code:201 userInfo:nil];
err = [NSError errorWithDomain:@"Server Issue" code:201 userInfo:nil];
}
else
{
parsedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
NSMutableDictionary *dict = [parsedData objectForKey:@"User"];

loginSuccessful = YES;
}
dispatch_semaphore_signal(semaphore);
}];
[task resume];

// but have the thread wait until the task is done

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

return err;
}

最佳答案

Rob 的回答告诉你如何做对,但没有告诉你犯了什么错误:

您有两个名为 err 的变量,它们完全不相关。看来你没有打开一些重要的警告,否则你的代码甚至都不会编译。

传递给完成 block 的参数 err 是来自 URL 请求的错误。您在不考虑超时错误的情况下替换了它 - 因此现在真正的错误丢失了。考虑到超时不是唯一的错误。

但是您设置的所有错误仅设置在完成 block 中传递给您的局部变量 err;他们根本不会触及调用者中的变量 err 。

附言。 JSON 处理中的几个严重错误。 JSON 可以采用 UTF-16 或 UTF-32 格式,在这种情况下,formattedData 将为 nil,并且您会错误地打印“服务器问题”。如果数据不是 JSON,则无法保证它包含 DOCTYPE 或 html,该测试绝对是垃圾。绰号为 JoeSmith 的用户会讨厌你。

将 NSJSONReadingAllowFragments 传递给 NSJSONSerialization 是无稽之谈。 dict 是不可变的;如果您尝试修改它,您的应用程序将会崩溃。您不检查解析器是否返回字典,不检查键“User”是否有值,也不检查该值是否为字典。这就是您的应用程序崩溃的多种方式。

关于ios - 使用信号量从异步调用返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31589242/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com