0

我使用块从一个类的响应中获取头字段,并且我必须在另一个类中获取它。如何立即获得块结果?

我实现这样的

在第一类代码:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    UserAuthentication *auth = [[UserAuthentication alloc]init]; 
    NSDictionary *dict = [auth getUserConfiguration]; 
    NSLog(@"%@",dict); 
} 

在userAuthentication类:

-(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; 
} 

这里我的问题是头等我越来越dict为空。

即使在userAuthentication类也是我变空。

但经过一段时间回调方法正在调用,然后我可以在completionHandler正确看到响应。

那么我如何才能在firstClass中获得响应?

回答

2

您误解了在后台线程中运行的异步操作的基本原理,并且操作完成时,它将为您提供完成块中的数据。

要在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); 

    }]; 
} 
+0

得到这个错误:函数'完成'的隐式声明在C99中是无效的 – Himanth

+0

所以我只好改变完成操作完成操作 – Himanth

+0

是的,这是一个错字错误,对不起。 –

1

您正在使用NSURLSession!它在后台线程上执行任务! 只有当您从服务器获得响应时才会调用完成块。当然,完成请求需要时间。您应该使用块完成请求并在完成时返回结果。

-(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]; 
} 

当您从第一个类调用上述代码时,它将在那里创建一个块,并且您将在块参数中获得所需的字典!

+0

如何当您尝试调用函数调用头等 – Himanth

+0

这种方法,自动填充展示函数名称,然后autoComplete将写入整个函数。 但是,你应该看看狮子的答案,以了解它。 – Rikh

1

你的方法应该是这样的,

-(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服务(从服务器)的响应中获取数据,因此需要一些时间来完成,所以你必须从webservice调用的完成处理程序返回数据,并且不能从完成处理程序返回数据,因此必须创建自己的完成处理程序和调用,如上所述。你可以访问resultDictionarycompletionHandler,你可以从这个completionHandler显示新的VC。

2

这东西你必须去习惯:这是有关互联网接入(有些东西不是与之相关的)任何不能立即返回 - 除非您愿意等待,请阻止您的用户界面,并让您的用户非常非常不高兴。

您必须以这样一种方式编写应用程序,使其可以处于四种状态:从不询问用户配置,询问用户配置,询问并接收用户配置,或询问用户配置和失败。在这种情况下,您的观点必须处理所有四种可能性,并且必须在情况变化时处理。

0

你必须在completionHandler的第一个类中调用一个方法。

  1. 创建类型YOURFIRSTCLASS的属性* myfirstclass在UserAuthentication类。

  2. 将带有“self”的firstclass传递给UserAuthentication对象。

  3. 建立在你的Firstclass可见方法 “ - (空)responseCaller:(NSDictionary的)字典”

  4. 呼叫你的回应方法,该方法

YOURFIRSTCLASS .H:

-(void)responseCaller:(NSDictionary)dict; 

YOURFIRSTCLASS .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); 
} 

UserAuthentication .H

#import "YOURFIRSTCLASS.h" 
@property (nonatomic) *myfirstclass; 

UserAuthentication .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; 
} 

类似的东西