我正在深入研究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
我想为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
...但我无法弄清楚如何将回调过程转换为块。无论如何可以给我一些方向吗?
提前感谢您的智慧!
顺便说一句,我只是在没有测试的情况下掀起了代码,所以如果有任何拼写错误我会道歉。
答案 0 :(得分:5)
诀窍是将完成块复制到iVar类,然后再调用它。
@property (nonatomic, copy) void (^errorHandler)(NSError *);
@property (nonatomic, copy) void (^successHandler)(NSString *);
这是一个方法,它保存两个块以供以后使用,然后调用另一个类方法:
- (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];
}
稍后 - 当我们想要完成的工作已经完成时,我们会调用另一个方法来运行块。在这个愚蠢的示例代码中,我们检查类属性self.error
是否为nil
。如果不是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;
}
答案 1 :(得分:3)
我们可以这样使用:
typedef void (^SuccessDataBlock)(NSMutableDictionary *);
@interface SuckyClassWrapper : NSObject <SuckyClassDelegate>
@property (nonatomic, retain) NSData *inputData;
@property (nonatomic, copy) SuccessDataBlock completionHandler;
+ (id)requestData:(NSData *)data successBlock:(SuccessDataBlock)handler;
@end
@implementation SuckyClassWrapper
@synthesize inputData;
@synthesize completionHandler;
- (id)initWithData:(NSData *)data completionHandler:(SuccessDataBlock)handler
{
self = [super init];
if (self != nil)
{
inputData = [data retain];
self.completionHandler = handler;
}
return self;
}
+ (id)requestData:(NSData *)data successBlock:(SuccessDataBlock)handler
{
return [[[self alloc] initWithData:data completionHandler:handler] autorelease];
}
//implement SuckyClass delegate
- (void)returnedSuckyData:(NSMutableDictionary *)data
{
self.completionHandler(data);
}
@end
用法:
SuckyClassWrapper *wrapper = [SuckyClassWrapper requestData:data successBlock:^(NSMutableDictionary *successData) {
//your code here
}];