Objective-C:如何为使用方法执行结果

时间:2016-10-09 18:19:01

标签: ios objective-c delegates objective-c-blocks completionhandler

对象X需要下载图像。它有图像的URL(可以是网络文件)。我有一个常见的imageHandler类,可以获取URL并获取imageData。我想要这个方法,能够使用完成块来自定义如何处理下载的图像。

我熟悉如何使用委托模式。 E.g

@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类的getImageFromURL:委托方法,委托为self。它符合ImageRequestor协议。

ImageHandler对象,存储url以在哈希表中委托映射。完成后,在委托上调用image:RetrievedForURL:withError :.在这种方法中,我对图像和错误采取行动。

如何使用完成块实现相同的效果,我将“我想对检索到的图像做什么”作为一段代码传递给我。

我看到的一种方法如下。但看起来它需要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>);
}

2 个答案:

答案 0 :(得分:4)

是的,你所展示的是这种做法的典型方式。看看Apple自己的API,看看他们是否也这样做。例如,-[NSURLSession dataTaskWithURL:completionHandler:],其声明为:

- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url 
                        completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;

答案 1 :(得分:0)

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
}];

这种东西在单人类中看起来好多了:]

希望它有所帮助, 祝你好运!!