Objective C: 有没有办法在另一个方法中调用一个方法的完成块?
Objective C: Is there a way to call a completion block for a method in another method?
我有多个 GET
API 请求方法在完成时调用完成块。这是一个例子。
- (void)getUserInfo
onSuccess:(void (^)(id))successBlock
onFailure:(void (^)(NSError *))failureBlock {
NSString *urlStr = [NSString stringWithFormat:@"%@/user/", baseUrl];
[manager GET:urlStr parameters:nil progress:nil
success:^(NSURLSessionTask *task, id responseObject) {
successBlock(responseObject);
}
failure:^(NSURLSessionTask *operation, NSError *error) {
failureBlock(error);
}];
}
但是,我注意到我在其他方法中重复了管理器 GET
请求代码。我想创建另一种方法来处理所有请求并删除重复代码。 URL 似乎是唯一改变的东西。但是,有一个缺陷。我需要调用 successBlock
让方法知道请求已经完成。
也许我需要完全走另一条路,做一些不同的事情。
您可以传递完成块,然后从处理所有 get 请求的最终方法中调用它们。为了简洁起见,我通常会制作将要重用的 typedef 的完成块。这是我的意思的一个例子(我添加了第二个示例方法,它也传递到中心 getRequestWithURLString:onSuccess:onFailure:
方法):
LLFakeManager.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^_Nullable SuccessCompletionBlock)(id responseObject);
typedef void (^_Nullable FailureCompletionBlock)(NSError *error);
@interface LLFakeManager : NSObject
- (void)getUserInfoOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock;
- (void)getBooksCheckedOutOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock;
@end
NS_ASSUME_NONNULL_END
LLFakeManager.m
#import "LLFakeManager.h"
@interface LLFakeManager()
- (void)getRequestWithURLString:(NSString *)urlString
onSuccess:(SuccessCompletionBlock)successBlock
onFailure:(FailureCompletionBlock)failureBlock;
@end
@implementation LLFakeManager
- (void)getUserInfoOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock {
NSString *urlStr = @"FakeUserUrlPath";
[self getRequestWithURLString:urlStr onSuccess:successBlock onFailure:failureBlock];
}
- (void)getBooksCheckedOutOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock {
NSString *urlString = @"FakeBooksUrlPath";
[self getRequestWithURLString:urlString onSuccess:successBlock onFailure:failureBlock];
}
// central method that will handle all the get requests
- (void)getRequestWithURLString:(NSString *)urlString
onSuccess:(SuccessCompletionBlock)successBlock
onFailure:(FailureCompletionBlock)failureBlock {
// some fake implementation here to do your request, then use the completion block passed in from whatever other method
if (successBlock) {
successBlock(@"responseObjectPassedBackHere");
}
}
@end
以及调用它的示例:
LLFakeManager *manager = [[LLFakeManager alloc] init];
[manager getUserInfoOnSuccess:^(id _Nonnull responseObject) {
NSLog(@"Here's my response object = %@", responseObject);
} onFailure:^(NSError * _Nonnull error) {
// no implementation but same idea
}];
会产生这个日志:
Here's my response object = responseObjectPassedBackHere
此站点:http://goshdarnblocksyntax.com 是一个方便的块语法列表,可能对您也有帮助。
这些块——如果它们具有相同的签名——它们可以沿着一系列方法传递。您的 GET 块带有一个不必要的第一个参数。 NSURLSessionTask *
,如果要 returned,应该同步 returned。将其移出区块签名将使您能够标准化区块。
用代码说比较容易...
// changed this method name so it would compile
- (void)getUserInfoOnSuccess:(void (^)(id))successBlock
onFailure:(void (^)(NSError *))failureBlock {
NSString *urlStr = [NSString stringWithFormat:@"%@/user/", baseUrl];
// two things: get the task as a return value (if you need it)
// pass the blocks directly, without nesting them in new blocks
NSURLSessionTask *task = [manager GET: urlStr
parameters: nil
progress: nil
success: successBlock
failure: failureBlock];
// do something with the task
}
要完成这项工作,请更改 GET 方法 return 类型并阻止签名...
- (NSURLSessionTask *)GET:(NSString *)url parameters:(id)params progress:(id)progress success:(void (^)(id))successBlock failure:(void (^)(NSError *))failureBlock {
// return the session task created here
return task
}
我有多个 GET
API 请求方法在完成时调用完成块。这是一个例子。
- (void)getUserInfo
onSuccess:(void (^)(id))successBlock
onFailure:(void (^)(NSError *))failureBlock {
NSString *urlStr = [NSString stringWithFormat:@"%@/user/", baseUrl];
[manager GET:urlStr parameters:nil progress:nil
success:^(NSURLSessionTask *task, id responseObject) {
successBlock(responseObject);
}
failure:^(NSURLSessionTask *operation, NSError *error) {
failureBlock(error);
}];
}
但是,我注意到我在其他方法中重复了管理器 GET
请求代码。我想创建另一种方法来处理所有请求并删除重复代码。 URL 似乎是唯一改变的东西。但是,有一个缺陷。我需要调用 successBlock
让方法知道请求已经完成。
也许我需要完全走另一条路,做一些不同的事情。
您可以传递完成块,然后从处理所有 get 请求的最终方法中调用它们。为了简洁起见,我通常会制作将要重用的 typedef 的完成块。这是我的意思的一个例子(我添加了第二个示例方法,它也传递到中心 getRequestWithURLString:onSuccess:onFailure:
方法):
LLFakeManager.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^_Nullable SuccessCompletionBlock)(id responseObject);
typedef void (^_Nullable FailureCompletionBlock)(NSError *error);
@interface LLFakeManager : NSObject
- (void)getUserInfoOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock;
- (void)getBooksCheckedOutOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock;
@end
NS_ASSUME_NONNULL_END
LLFakeManager.m
#import "LLFakeManager.h"
@interface LLFakeManager()
- (void)getRequestWithURLString:(NSString *)urlString
onSuccess:(SuccessCompletionBlock)successBlock
onFailure:(FailureCompletionBlock)failureBlock;
@end
@implementation LLFakeManager
- (void)getUserInfoOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock {
NSString *urlStr = @"FakeUserUrlPath";
[self getRequestWithURLString:urlStr onSuccess:successBlock onFailure:failureBlock];
}
- (void)getBooksCheckedOutOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock {
NSString *urlString = @"FakeBooksUrlPath";
[self getRequestWithURLString:urlString onSuccess:successBlock onFailure:failureBlock];
}
// central method that will handle all the get requests
- (void)getRequestWithURLString:(NSString *)urlString
onSuccess:(SuccessCompletionBlock)successBlock
onFailure:(FailureCompletionBlock)failureBlock {
// some fake implementation here to do your request, then use the completion block passed in from whatever other method
if (successBlock) {
successBlock(@"responseObjectPassedBackHere");
}
}
@end
以及调用它的示例:
LLFakeManager *manager = [[LLFakeManager alloc] init];
[manager getUserInfoOnSuccess:^(id _Nonnull responseObject) {
NSLog(@"Here's my response object = %@", responseObject);
} onFailure:^(NSError * _Nonnull error) {
// no implementation but same idea
}];
会产生这个日志:
Here's my response object = responseObjectPassedBackHere
此站点:http://goshdarnblocksyntax.com 是一个方便的块语法列表,可能对您也有帮助。
这些块——如果它们具有相同的签名——它们可以沿着一系列方法传递。您的 GET 块带有一个不必要的第一个参数。 NSURLSessionTask *
,如果要 returned,应该同步 returned。将其移出区块签名将使您能够标准化区块。
用代码说比较容易...
// changed this method name so it would compile
- (void)getUserInfoOnSuccess:(void (^)(id))successBlock
onFailure:(void (^)(NSError *))failureBlock {
NSString *urlStr = [NSString stringWithFormat:@"%@/user/", baseUrl];
// two things: get the task as a return value (if you need it)
// pass the blocks directly, without nesting them in new blocks
NSURLSessionTask *task = [manager GET: urlStr
parameters: nil
progress: nil
success: successBlock
failure: failureBlock];
// do something with the task
}
要完成这项工作,请更改 GET 方法 return 类型并阻止签名...
- (NSURLSessionTask *)GET:(NSString *)url parameters:(id)params progress:(id)progress success:(void (^)(id))successBlock failure:(void (^)(NSError *))failureBlock {
// return the session task created here
return task
}