簡體   English   中英

如何立即獲得結果塊?

[英]How to get result in blocks immediately?

我正在使用塊來從一個類的響應中獲取標頭字段,而我必須在另一類中獲取它。

我實現了這樣的代碼

頭等艙:

- (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設為null。

即使在userAuthentication類中,我也得到null。

但一段時間后回調方法調用,然后我可以看到正確的響應completionHandler

那么我如何在firstClass上獲得回應?

您誤解了在后台線程中運行的異步操作的基本原理,當操作完成時,它將在完成塊中提供數據。

要在第二類的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);

   }];
}

這是您必須習慣的事情:與互聯網訪問相關的任何內容(以及與互聯網無關的某些內容)都無法立即返回-除非您願意等待它,阻塞用戶界面並吸引用戶非常非常不開心

您必須以一種可以處於四種狀態的方式來編寫應用程序:絕不詢問用戶配置,詢問用戶配置,詢問並接收用戶配置,詢問用戶配置而失敗。 在這種情況下,您的視圖必須處理所有四種可能性,並且必須在情況發生變化時進行處理。

您正在使用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];
}

當您從第一個類調用上述代碼時,它將在此處創建一個塊,您將在block參數中獲得所需的字典!

你的方法應該像

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

    }];

 }

因為您將獲取數據以響應webservice(從服務器),所以需要花費一些時間才能完成,因此您必須從webservice調用的完成處理程序中返回數據,並且無法從完成處理程序中返回數據,因此必須創建自己的完成處理程序並按我上面提到的方式打電話。 您可以訪問resultDictionarycompletionHandler ,你可以展示這種新的VC completionHandler

您必須在您的completeHandler中的第一個類中調用一個方法。

  1. 在UserAuthentication Class中創建類型YOURFIRSTCLASS * myfirstclass的屬性。

  2. 將帶有“ self”的頭等艙傳遞給UserAuthentication對象。

  3. 在您的第一類“-(void)responseCaller:(NSDictionary)dict”中創建可見方法

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

用戶驗證.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;
}

像這樣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM