带有完成和参数的块
Block with completion and arguments
我是积木新手。我正在尝试分析以下代码的工作原理。
据我了解,此特定方法有一个块并且 returns a
NSURLSessionDataTask
。 getTotalFollowersFrom
是方法的名称。 (NSString*)influencerId
是调用此方法时传递的userId。使用 WithCompletion:
以便我们知道该方法何时完成 Api 调用。 Void
是什么块returns。插入符号 (^)
用于定义块。以下(id _Nullable likesCountRequestResponse, NSError * _Nullable error)completion
为参数。这是我不明白的。根据文档 arguments 在块内有 return 值。我看到 return 是 NSURLSessionDataTask
的 return result;
,但我不明白块参数的值 return 是如何产生的。我错过了什么?谁能给我解释一下吗?
- (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);
}
您的示例不完整。所以,让我们考虑一个 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
。那个方法无疑是在给你打卡
作为个人喜好问题,我认为 result
与 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
引用被返回,我们保存它,这样我们就可以有一个取消按钮,例如,将取消该异步网络请求。
但是,简而言之,不要将 networkRequestWithCompletion
立即返回的 NSURLSessionTask
引用(让我们可以选择稍后取消请求)与块的参数混为一谈,这我们用来向调用者提供网络请求的结果。
我是积木新手。我正在尝试分析以下代码的工作原理。
据我了解,此特定方法有一个块并且 returns a
NSURLSessionDataTask
。 getTotalFollowersFrom
是方法的名称。 (NSString*)influencerId
是调用此方法时传递的userId。使用 WithCompletion:
以便我们知道该方法何时完成 Api 调用。 Void
是什么块returns。插入符号 (^)
用于定义块。以下(id _Nullable likesCountRequestResponse, NSError * _Nullable error)completion
为参数。这是我不明白的。根据文档 arguments 在块内有 return 值。我看到 return 是 NSURLSessionDataTask
的 return result;
,但我不明白块参数的值 return 是如何产生的。我错过了什么?谁能给我解释一下吗?
- (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);
}
您的示例不完整。所以,让我们考虑一个 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
。那个方法无疑是在给你打卡
作为个人喜好问题,我认为 result
与 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
引用被返回,我们保存它,这样我们就可以有一个取消按钮,例如,将取消该异步网络请求。
但是,简而言之,不要将 networkRequestWithCompletion
立即返回的 NSURLSessionTask
引用(让我们可以选择稍后取消请求)与块的参数混为一谈,这我们用来向调用者提供网络请求的结果。