[英]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調用的完成處理程序中返回數據,並且無法從完成處理程序中返回數據,因此必須創建自己的完成處理程序並按我上面提到的方式打電話。 您可以訪問resultDictionary
在completionHandler
,你可以展示這種新的VC completionHandler
。
您必須在您的completeHandler中的第一個類中調用一個方法。
在UserAuthentication Class中創建類型YOURFIRSTCLASS * myfirstclass的屬性。
將帶有“ self”的頭等艙傳遞給UserAuthentication對象。
在您的第一類“-(void)responseCaller:(NSDictionary)dict”中創建可見方法
在您的響應方法中調用該方法
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.