我是塊新手。我正在嘗試分析以下代碼的作業原理。
據我了解,此特定方法有一個塊并回傳一個
NSURLSessionDataTask
. getTotalFollowersFrom是方法的名稱。(NSString*)influencerId是呼叫此方法時傳遞的 userId。WithCompletion:使用,因此我們知道該方法何時完成 Api 呼叫。Void是塊回傳的內容。插入符號(^)用于定義塊。以下(id _Nullable likesCountRequestResponse, NSError * _Nullable error)completion為論據。這是我不明白的。根據檔案,引數在塊內有回傳值。我看到return result;回傳的,NSURLSessionDataTask但我不明白值如何回傳塊的引數。我錯過了什么?誰能給我解釋一下?
- (NSURLSessionDataTask *)getTotalLikesFrom:(NSString*)userId withCompletion:(void (^)(id _Nullable likesCountRequestResponse, NSError * _Nullable error))completion {
NSString* postString = [NSString stringWithFormat:@"apicall/%@", userId];
@weakify(self)
NSURLSessionDataTask *result = [self GET:postString parameters:nil completion:^(OVCResponse * _Nullable response, NSError * _Nullable error) {
@strongify(self)
[self handleResponse:response error:error adjustErrorBlock:self.commonValidationErrorAdjustBlock completion:completion];
}];
return result;
}
- (void)handleResponse:(nullable OVCResponse *)response error:(nullable NSError *)error adjustErrorBlock:(nullable ApiClientv2AdjustErrorBlock)adjustErrorBlock completion:(void (^)(id _Nullable result, NSError * _Nullable error))completion
{
if (response.HTTPResponse.statusCode >= 500)
{
error = nil != error ? error : NSError.com_eight_APIServiceUnknownError; [SentrySDK captureError:error];
}
else
{
error = nil != error ? error : NSError.com_eight_APIServiceUnknownError;
}
id result = nil == error ? response.result : nil;
completion(result, error);
}
uj5u.com熱心網友回復:
你的例子不完整。所以,讓我們考慮一個MCVE:
- (NSURLSessionDataTask *)networkRequestWithCompletion:(void (^)(NSDictionary * _Nullable object, NSError * _Nullable error))completion {
NSURL *url = [NSURL URLWithString:@"https://httpbin.org/get"];
NSURLSessionDataTask *task = [NSURLSession.sharedSession dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!data || error) {
completion(nil, error);
return;
}
NSError *parseError;
NSDictionary *resultObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
if (parseError) {
completion(nil, parseError);
return;
}
completion(resultObject, nil);
}];
[task resume];
return task;
}
這將執行網路請求并決議 JSON。在該方法中,您將看到對以下內容的參考:
completion(nil, error);
或者:
completion(resultObject, nil);
這就是將資料傳遞回呼叫者的方式。該方法在呼叫時提供塊的引數completion。因此,可以為該方法提供一個塊并使用這兩個引數:
[self networkRequestWithCompletion:^(NSDictionary *dictionary, NSError *error) {
if (error) {
NSLog(@"error = %@", error);
return;
}
// you can access the `dictionary` parameter here ...
NSLog(@"dictionary = %@", dictionary);
}];
// ... but you cannot reference the `dictionary` or `error` parameters here
// because the above runs asynchronously (i.e., later).
在您在問題中提供的代碼段中,您沒有completion在任何地方呼叫。但請注意,它提供給handleResponse. 該方法無疑是在為您呼叫塊。
作為個人喜好問題,我認為resultfor the的選擇NSURLSessionDataTask有點令人困惑。所以在我的例子中,我給它起了一個更好的名字,task,以明確它是NSURLSessionTask物件,而不是網路請求的結果。
但是這個物件的目的是什么?這樣呼叫者可以選擇取消請求,如果它愿意。例如,您可能有:
@interface ViewController ()
@property (nonatomic, weak) NSURLSessionTask *task;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.task = [self networkRequestWithCompletion:^(NSDictionary *dictionary, NSError *error) {
if (error) {
NSLog(@"error = %@", error);
return;
}
NSLog(@"dictionary = %@", dictionary);
}];
}
- (IBAction)didTapCancelButton:(id)sender {
[self.task cancel];
}
...
@end
因此,NSURLSessionTask回傳參考,我們將其保存,以便我們可以擁有例如取消該異步網路請求的取消按鈕。
但是,簡而言之,不要將NSURLSessionTask立即回傳的參考networkRequestWithCompletion(給我們稍后取消請求的選項)與塊的引數混為一談,我們用它來為呼叫者提供網路請求的結果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/419202.html
標籤:
下一篇:為什么谷歌說我的網站不適合手機
