Objective-C:如何将完成块提供给使用方法执行结果的方法
Objective-C: How to give a completion block to a method that uses a result from the method execution
对象 X 需要下载图像。它有 URL 个图像(可以是网络文件)。我有一个通用的 imageHandler class 可以接受 URL 并获取 imageData。我想要这个方法,能够使用完成块来自定义如何处理下载的图像。
我很熟悉如何使用委托模式来做到这一点。例如
@protocol ImageHandler: NSObject
-(void) getImageFromURL:(NSURL *)url forDelegate:(id <ImageRequestor>)delegate;
@end
@protocol ImageRequestor: NSObject
-(void) image:(UIImage *) image RetrievedForURL:(NSURL *)url withError:(NSError *)error;
@end
所以,基本上 objectX class getImageFromURL:delegate 方法以委托作为自身。符合ImageRequestor协议。
ImageHandler 对象,存储 url 以在散列 table 中委托映射。完成后,在委托上调用 image:RetrievedForURL:withError:。在这种方法中,我对图像和错误进行操作。
如何使用将 "what i want to do with the retrieved image" 作为一段代码传递的完成块实现相同的效果。
我看到的一种方法如下。但看起来它需要 ImageHandler 方法实现调用带有特定参数的完成。这是实现它的公认方法吗(即完成处理程序依赖于接收它的方法以使用正确的参数调用它)?
@protocol ImageHandler: NSObject
-(void) getImageFromURL:(NSURL *)url withCompletionHandler:(void (^)(UIImage *image, NSError * err))completionBlock;
@end
getImageFromURL:(NSURL *)url withCompletionHandler:(void (^)(UIImage *image, NSError * err))completionBlock
的实现看起来像
getImageFromURL:(NSURL *)url withCompletionHandler:(void (^)(UIImage *image, NSError * err))completionBlock
{
//Get UIImage from URL, store it UIIMage ObjectX
//if error happens, store it in NSError objectY, else it is nil
//call completion handler
completionBlock(<UIIMage objectX>,<NSError objectY>);
}
是的,您展示的是执行此操作的典型方法。查看 Apple 自己的 API,发现它们以相同的方式进行操作。例如-[NSURLSession dataTaskWithURL:completionHandler:]
,其声明为:
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url
completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
在您的 ImageRequestor.h 文件中写入以下内容:
#import <Foundation/Foundation.h>
// Here you define your custom response block with the desired parameters
// That in this case are UIImage and NSError
typedef void (^ResponseBlock)(UIImage *image, NSError *error);
@interface ImageRequestor : NSObject
// Here you define the method that use your custom response block
- (void)getImageFromURL:(NSURL *)url withCompletionHandler:(ResponseBlock)completionBlock;
@end
几乎完成,现在打开您的 ImageRequestor.m 文件并添加以下内容:
#import "ImageRequestor.h"
@implementation ImageRequestor
- (void)getImageFromURL:(NSURL *)url withCompletionHandler:(ResponseBlock)completionBlock {
// Do all your stuff to get the image and the error
// And set them into your completion block
// if there is no error that should be nil
// completionBlock(YourFetchedImage, YourFetchedError);
// completionBlock(nil, YourFetchedError);
completionBlock(YourFetchedImage, nil);
}
@end
最后你可以这样调用它:
ImageRequestor *imageRequestor = [[ImageRequestor alloc] init];
[imageRequestor getImageFromURL:yourURL withCompletionHandler:^(UIImage *image, NSError *error) {
// Your implementation in here
}];
这种东西在单例中看起来好多了 class :]
希望对您有所帮助,
祝你好运!!
对象 X 需要下载图像。它有 URL 个图像(可以是网络文件)。我有一个通用的 imageHandler class 可以接受 URL 并获取 imageData。我想要这个方法,能够使用完成块来自定义如何处理下载的图像。
我很熟悉如何使用委托模式来做到这一点。例如
@protocol ImageHandler: NSObject
-(void) getImageFromURL:(NSURL *)url forDelegate:(id <ImageRequestor>)delegate;
@end
@protocol ImageRequestor: NSObject
-(void) image:(UIImage *) image RetrievedForURL:(NSURL *)url withError:(NSError *)error;
@end
所以,基本上 objectX class getImageFromURL:delegate 方法以委托作为自身。符合ImageRequestor协议。
ImageHandler 对象,存储 url 以在散列 table 中委托映射。完成后,在委托上调用 image:RetrievedForURL:withError:。在这种方法中,我对图像和错误进行操作。
如何使用将 "what i want to do with the retrieved image" 作为一段代码传递的完成块实现相同的效果。
我看到的一种方法如下。但看起来它需要 ImageHandler 方法实现调用带有特定参数的完成。这是实现它的公认方法吗(即完成处理程序依赖于接收它的方法以使用正确的参数调用它)?
@protocol ImageHandler: NSObject
-(void) getImageFromURL:(NSURL *)url withCompletionHandler:(void (^)(UIImage *image, NSError * err))completionBlock;
@end
getImageFromURL:(NSURL *)url withCompletionHandler:(void (^)(UIImage *image, NSError * err))completionBlock
的实现看起来像
getImageFromURL:(NSURL *)url withCompletionHandler:(void (^)(UIImage *image, NSError * err))completionBlock
{
//Get UIImage from URL, store it UIIMage ObjectX
//if error happens, store it in NSError objectY, else it is nil
//call completion handler
completionBlock(<UIIMage objectX>,<NSError objectY>);
}
是的,您展示的是执行此操作的典型方法。查看 Apple 自己的 API,发现它们以相同的方式进行操作。例如-[NSURLSession dataTaskWithURL:completionHandler:]
,其声明为:
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url
completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
在您的 ImageRequestor.h 文件中写入以下内容:
#import <Foundation/Foundation.h>
// Here you define your custom response block with the desired parameters
// That in this case are UIImage and NSError
typedef void (^ResponseBlock)(UIImage *image, NSError *error);
@interface ImageRequestor : NSObject
// Here you define the method that use your custom response block
- (void)getImageFromURL:(NSURL *)url withCompletionHandler:(ResponseBlock)completionBlock;
@end
几乎完成,现在打开您的 ImageRequestor.m 文件并添加以下内容:
#import "ImageRequestor.h"
@implementation ImageRequestor
- (void)getImageFromURL:(NSURL *)url withCompletionHandler:(ResponseBlock)completionBlock {
// Do all your stuff to get the image and the error
// And set them into your completion block
// if there is no error that should be nil
// completionBlock(YourFetchedImage, YourFetchedError);
// completionBlock(nil, YourFetchedError);
completionBlock(YourFetchedImage, nil);
}
@end
最后你可以这样调用它:
ImageRequestor *imageRequestor = [[ImageRequestor alloc] init];
[imageRequestor getImageFromURL:yourURL withCompletionHandler:^(UIImage *image, NSError *error) {
// Your implementation in here
}];
这种东西在单例中看起来好多了 class :]
希望对您有所帮助, 祝你好运!!