如何立即得到块中的结果?
How to get result in blocks immediately?
我正在使用块从一个 class 中的响应中获取 header 字段,我必须在另一个 class 中获取它。
我实现了这样的代码
第一个class:
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
NSDictionary *dict = [auth getUserConfiguration];
NSLog(@"%@",dict);
}
在用户身份验证中 class:
-(NSDictionary *)getUserConfiguration;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
}
}] resume];
NSLog(@"%@",resultDictionary);
return resultDictionary;
}
我的问题首先出现在 class 我得到的 dict
为空。
即使在 userAuthentication
class 中我也得到空值。
但一段时间后回调方法正在调用,然后我可以在 completionHandler
中正确看到响应。
那么我怎样才能在 firstClass 中得到回应?
您正在使用 NSURLSession!它在后台线程上执行任务!
仅当您从服务器获得响应时才会调用完成块。完成请求自然需要时间。您应该使用块来完成请求并 return 完成时的结果。
-(void)getUserConfigurationAndOnCompletion:(void(ˆ)(NSDictionary *dict, NSError *error))completion;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
//This will call the block in the first class with the result dictionary
dispatch_async(dispatch_get_main_queue(), ^{
if(!error){
completion(resultDictionary,nil);
}else{
completion(nil,error);
}
});
}] resume];
}
当您从第一个 class 调用上述代码时,它将在那里创建一个块,您将在块参数中获得所需的字典!
你的方法应该是这样的,
-(void)getUserConfigurationwithCompletionHandler : (void (^)(NSDictionary* resultDictionary))completionHandler
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
completionHandler(resultDictionary);
}
}] resume];
NSLog(@"%@",resultDictionary);
}
您可以像这样访问它,
- (void)viewDidLoad {
[super viewDidLoad];
[self getUserConfigurationwithCompletionHandler:^(NSDictionary *resultDictionary) {
// you can acess result dictionary here
NSLog(@"%@",resultDictionary);
}];
}
因为您将(从服务器)获取响应 web 服务的数据,所以需要一些时间才能完成,所以您必须 return 来自 web 服务调用的完成处理程序的数据,而您不能 return 来自完成处理程序的数据,因此您必须创建自己的完成处理程序并调用我上面提到的。您可以在 completionHandler
中访问 resultDictionary
,并且您可以从这个 completionHandler
中显示新的 VC。
您误解了在后台线程中运行的异步操作的基本原理,当操作完成时它会在完成块中为您提供数据。
要在第二个 class 的 viewDidLoad 方法中获得响应,您需要使用块。如下图
-(void)getUserConfigurationOnCompletion:(void (^)(NSDictionary *))completion
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
// Call completion with parameter
completion(resultDictionary);
}
}] resume];
}
并在 viewDidLoad 中像这样使用它
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
[auth getUserConfigurationOnCompletion:^(NSDictionary *dict){
// do necessary work with response dictionary here
NSLog(@"%@",dict);
}];
}
这是你必须习惯的事情:任何与互联网访问相关的东西(以及一些与之无关的东西)都不能立即返回 - 除非你愿意等待它,否则阻止你的用户界面,并让您的用户非常非常不高兴。
你必须以这样一种方式编写你的应用程序,它可以处于四种状态:从未请求用户配置、请求用户配置、已请求并收到用户配置或已请求用户配置失败。在这种情况下,您的视图必须处理所有四种可能性,并且必须在情况发生变化时处理。
您必须在 completionHandler 的第一个 class 中调用一个方法。
在您的 UserAuthentication Class 中创建类型为 YOURFIRSTCLASS *myfirstclass 的 属性。
将您的第一个 class 和 "self" 传递给 UserAuthentication 对象。
在你的第一个class中创建可见方法“-(void)responseCaller:(NSDictionary)dict”
调用响应方法中的方法
你的第一堂课.h:
-(void)responseCaller:(NSDictionary)dict;
你的第一堂课.m
-(void)responseCaller:(NSDictionary)dict
{NSLog(@"%@",dict);}
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
auth.myfirstclass = self;
NSDictionary *dict = [auth getUserConfiguration];
NSLog(@"%@",dict);
}
用户身份验证.h
#import "YOURFIRSTCLASS.h"
@property (nonatomic) *myfirstclass;
用户身份验证.m
-(NSDictionary *)getUserConfiguration;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
__weak myfirstclassSave = myfirstclass;
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
[myfirstclassSave responseCaller:resultDictionary ];
}
}] resume];
return resultDictionary;
}
类似的东西
我正在使用块从一个 class 中的响应中获取 header 字段,我必须在另一个 class 中获取它。
我实现了这样的代码
第一个class:
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
NSDictionary *dict = [auth getUserConfiguration];
NSLog(@"%@",dict);
}
在用户身份验证中 class:
-(NSDictionary *)getUserConfiguration;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
}
}] resume];
NSLog(@"%@",resultDictionary);
return resultDictionary;
}
我的问题首先出现在 class 我得到的 dict
为空。
即使在 userAuthentication
class 中我也得到空值。
但一段时间后回调方法正在调用,然后我可以在 completionHandler
中正确看到响应。
那么我怎样才能在 firstClass 中得到回应?
您正在使用 NSURLSession!它在后台线程上执行任务! 仅当您从服务器获得响应时才会调用完成块。完成请求自然需要时间。您应该使用块来完成请求并 return 完成时的结果。
-(void)getUserConfigurationAndOnCompletion:(void(ˆ)(NSDictionary *dict, NSError *error))completion;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
//This will call the block in the first class with the result dictionary
dispatch_async(dispatch_get_main_queue(), ^{
if(!error){
completion(resultDictionary,nil);
}else{
completion(nil,error);
}
});
}] resume];
}
当您从第一个 class 调用上述代码时,它将在那里创建一个块,您将在块参数中获得所需的字典!
你的方法应该是这样的,
-(void)getUserConfigurationwithCompletionHandler : (void (^)(NSDictionary* resultDictionary))completionHandler
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
completionHandler(resultDictionary);
}
}] resume];
NSLog(@"%@",resultDictionary);
}
您可以像这样访问它,
- (void)viewDidLoad {
[super viewDidLoad];
[self getUserConfigurationwithCompletionHandler:^(NSDictionary *resultDictionary) {
// you can acess result dictionary here
NSLog(@"%@",resultDictionary);
}];
}
因为您将(从服务器)获取响应 web 服务的数据,所以需要一些时间才能完成,所以您必须 return 来自 web 服务调用的完成处理程序的数据,而您不能 return 来自完成处理程序的数据,因此您必须创建自己的完成处理程序并调用我上面提到的。您可以在 completionHandler
中访问 resultDictionary
,并且您可以从这个 completionHandler
中显示新的 VC。
您误解了在后台线程中运行的异步操作的基本原理,当操作完成时它会在完成块中为您提供数据。
要在第二个 class 的 viewDidLoad 方法中获得响应,您需要使用块。如下图
-(void)getUserConfigurationOnCompletion:(void (^)(NSDictionary *))completion
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
// Call completion with parameter
completion(resultDictionary);
}
}] resume];
}
并在 viewDidLoad 中像这样使用它
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
[auth getUserConfigurationOnCompletion:^(NSDictionary *dict){
// do necessary work with response dictionary here
NSLog(@"%@",dict);
}];
}
这是你必须习惯的事情:任何与互联网访问相关的东西(以及一些与之无关的东西)都不能立即返回 - 除非你愿意等待它,否则阻止你的用户界面,并让您的用户非常非常不高兴。
你必须以这样一种方式编写你的应用程序,它可以处于四种状态:从未请求用户配置、请求用户配置、已请求并收到用户配置或已请求用户配置失败。在这种情况下,您的视图必须处理所有四种可能性,并且必须在情况发生变化时处理。
您必须在 completionHandler 的第一个 class 中调用一个方法。
在您的 UserAuthentication Class 中创建类型为 YOURFIRSTCLASS *myfirstclass 的 属性。
将您的第一个 class 和 "self" 传递给 UserAuthentication 对象。
在你的第一个class中创建可见方法“-(void)responseCaller:(NSDictionary)dict”
调用响应方法中的方法
你的第一堂课.h:
-(void)responseCaller:(NSDictionary)dict;
你的第一堂课.m
-(void)responseCaller:(NSDictionary)dict
{NSLog(@"%@",dict);}
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
auth.myfirstclass = self;
NSDictionary *dict = [auth getUserConfiguration];
NSLog(@"%@",dict);
}
用户身份验证.h
#import "YOURFIRSTCLASS.h"
@property (nonatomic) *myfirstclass;
用户身份验证.m
-(NSDictionary *)getUserConfiguration;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
__weak myfirstclassSave = myfirstclass;
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
[myfirstclassSave responseCaller:resultDictionary ];
}
}] resume];
return resultDictionary;
}
类似的东西