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 中得到响应呢?

4

5 回答 5

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

   }];
}
于 2016-10-18T09:46:17.360 回答
2

这是你必须习惯的事情:任何与互联网访问相关的东西(以及一些与它无关的东西)都不能立即返回 - 除非你愿意等待它,阻止你的用户界面,并让你的用户非常非常不开心。

你必须以这样一种方式编写你的应用程序,它可以处于四种状态:从未要求用户配置,要求用户配置,已要求并收到用户配置,或已要求用户配置但失败。在这种情况下,您的视图必须处理所有四种可能性,并且必须在情况发生变化时进行处理。

于 2016-10-18T09:49:04.247 回答
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];
}

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

于 2016-10-18T09:42:57.427 回答
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 服务(来自服务器),因此需要一些时间才能完成,因此您必须从 Web 服务调用的完成处理程序返回数据,并且您无法从完成处理程序返回数据,因此您必须创建自己的完成处理程序并像我上面提到的那样打电话。您可以访问resultDictionarycompletionHandler从中显示新的 VC completionHandler

于 2016-10-18T09:43:14.357 回答
0

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

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

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

  3. 在您的第一类“-(void)responseCaller:(NSDictionary)dict”中创建可见方法

  4. 在您的响应方法中调用该方法

你的第一课.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;
}

类似的东西

于 2016-10-18T09:55:22.603 回答