@protocol SomeObjectDelegate@required- (voID)stuffDone:(ID)anObject;- (voID)stuffFailed;@end@interface SomeObject : NSObject{}@end
现在,我已经决定,虽然我可以让另一个类实现stuffDone:委托方法,我决定,我想封装进程到一个块,它写在接近SomeObject被实例化,调用等。我该怎么做呢?或者换句话说,如果你看看this着名的文章块(在Replace Callbacks部分);我怎么可能在SomeObject中编写一个方法接受completionHandler:of sort?
解决方法 它听起来像你想要与一个现有的类进行通信,设计为接受委托对象。有多种方法,包括:>使用类别添加适当方法的基于块的变体;
>使用派生类添加基于块的变体;和
>编写一个实现协议并调用你的块的类。
这里有一种方法(3)。首先让我们假设你的SomeObject是:
@protocol SomeObjectDelegate@required- (voID)stuffDone:(ID)anObject;- (voID)stuffFailed;@end@interface SomeObject : NSObject{}+ (voID) testCallback:(ID<SomeObjectDelegate>)delegate;@end@implementation SomeObject+ (voID) testCallback:(ID<SomeObjectDelegate>)delegate{ [delegate stuffDone:[NSNumber numberWithInt:42]]; [delegate stuffFailed];}@end
所以我们有一些方法来测试 – 你会有一个真正的SomeObject。
现在定义一个实现协议并调用提供的块的类:
#import "SomeObject.h"typedef voID (^StuffDoneBlock)(ID anObject);typedef voID (^StuffFailedBlock)();@interface SomeObjectBlockDelegate : NSObject<SomeObjectDelegate>{ StuffDoneBlock stuffDoneCallback; StuffFailedBlock stuffFailedCallback;}- (ID) initWithOnDone:(StuffDoneBlock)done andOnFail:(StuffFailedBlock)fail;- (voID)dealloc;+ (SomeObjectBlockDelegate *) someObjectBlockDelegateWithOnDone:(StuffDoneBlock)done andOnFail:(StuffFailedBlock)fail;// protocol- (voID)stuffDone:(ID)anObject;- (voID)stuffFailed;@end
此类保存您传递的块,并调用它们以响应协议回调。实现很简单:
@implementation SomeObjectBlockDelegate- (ID) initWithOnDone:(StuffDoneBlock)done andOnFail:(StuffFailedBlock)fail{ if (self = [super init]) { // copy blocks onto heap stuffDoneCallback = Block_copy(done); stuffFailedCallback = Block_copy(fail); } return self;}- (voID)dealloc{ Block_release(stuffDoneCallback); Block_release(stuffFailedCallback); [super dealloc];}+ (SomeObjectBlockDelegate *) someObjectBlockDelegateWithOnDone:(StuffDoneBlock)done andOnFail:(StuffFailedBlock)fail{ return (SomeObjectBlockDelegate *)[[[SomeObjectBlockDelegate alloc] initWithOnDone:done andOnFail:fail] autorelease];}// protocol- (voID)stuffDone:(ID)anObject{ stuffDoneCallback(anObject);}- (voID)stuffFailed{ stuffFailedCallback();}@end
你需要记住的唯一的事情是Block_copy()块初始化时和Block_release()他们以后 – 这是因为块是堆栈分配和你的对象可能比它的创建堆栈框架更长; Block_copy()在堆中创建一个副本。
现在你可以通过一个基于委托的方法传递它块:
[SomeObject testCallback:[SomeObjectBlockDelegate someObjectBlockDelegateWithOnDone:^(ID anObject) { NSLog(@"Done: %@",anObject); } andOnFail:^{ NSLog(@"Failed"); } ]];
您可以使用此技术来封装任何协议的块。
ARC附录
响应注释:要使这个ARC兼容只是删除对Block_copy()的调用留下直接赋值:
stuffDoneCallback = done;stuffFailedCallback = fail;
并删除dealloc方法。您还可以更改Blockcopy以进行复制,即stuffDoneCallback = [完成复制];这是您可能认为从阅读ARC文档需要的。但是它不是作为一个强变量,导致ARC保留分配的值 – 并保留一个堆栈块将其复制到堆。因此,生成的ARC代码在有或没有副本的情况下产生相同的结果。
总结以上是内存溢出为你收集整理的objective-c – 如何简化回调逻辑与块?全部内容,希望文章能够帮你解决objective-c – 如何简化回调逻辑与块?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)