如何创建一个包装器来为使用回调的类使用块?

Bea*_*red 4 iphone objective-c ios objective-c-blocks

我正在深入研究iOS编程,我正在学习如何使用块.我有一个糟糕的,过度设计的库,我正在我的项目中使用它,它使用一个回调方法来处理所有数据请求...

@protocol SuckyClassDelegate <NSObject>
-(void)returnedSuckyData:(NSMutableDictionary*)data;
@end

@interface SuckyClass: NSObject
@property (nonatomic, weak) id<SuckyClassDelegate> delegate;
-(void)getSuckyData;
@end

@interface MyViewController: UIViewController <SuckyClassDelegate>
-(void)requestDataFromSuckyClass;
@end
Run Code Online (Sandbox Code Playgroud)

我想为SuckyClass创建一个包装类,允许我在需要从SuckyClass访问数据时使用块,但我不知道如何做到这一点.我想要这样的东西......

@interface SuckyClassWrapper
- (void)requestDataWithSuccessBlock:(void(^)((NSMutableDictionary*)data))successBlock;
@end

@implementation MyViewController
-(void)requestDataFromSuckyClass {
   SuckyClassWrapper *wrapper = [[SuckyClassWrapper alloc] init];
   [wrapper requestDataWithSuccessBlock:^(NSMutableDictionary *data) {
       NSLog(@"%@", data);
   }
}
@end
Run Code Online (Sandbox Code Playgroud)

...但我无法弄清楚如何将回调过程转换为块.无论如何可以给我一些方向吗?

提前感谢您的智慧!

顺便说一下,我只是在没有测试的情况下掀起代码,所以如果有任何错别字我会道歉.

red*_*ulb 5

诀窍是将完成块复制到iVar类,然后可以调用.

@property (nonatomic, copy) void (^errorHandler)(NSError *);
@property (nonatomic, copy) void (^successHandler)(NSString *);
Run Code Online (Sandbox Code Playgroud)

这是一个方法,它保存两个块以供以后使用,然后调用另一个类方法:

- (void)methodWithErrorHandler:(void(^)(NSError *error))errorBlock successHandler: (void(^)(NSString *data))successBlock
{
    // Copy the blocks to use later
    self.successHandler = successBlock;
    self.errorHandler = errorBlock;

    // Run code
    [self doOtherThings];
}
Run Code Online (Sandbox Code Playgroud)

后来 - 当我们想要做的事情已经完成时,我们有另一种方法,我们称之为运行块.在这种无聊的示例代码中我们检查,看是否有类属性self.errornil.如果不是nil,我们将该错误发送到我们保存的错误块.如果是nil,我们将传递self.data给成功块.

- (void)finishThingsUp
{
    // Check to see if we should call the error block or the success block
    if (self.error) {
        self.errorHandler(self.error);
    } else {
        self.successHandler(self.data);
    }
    // Clean up the blocks
    self.errorHandler = nil;
    self.successHandler = nil;
}
Run Code Online (Sandbox Code Playgroud)