objective-c – 如何简化回调逻辑与块?

objective-c – 如何简化回调逻辑与块?,第1张

概述让我们说,我需要与一个提供协议的类进行通信,并在 *** 作完成时调用委托方法,如下所示: @protocol SomeObjectDelegate@required- (void)stuffDone:(id)anObject;- (void)stuffFailed;@end@interface SomeObject : NSObject{}@end 现在,我已经决定,虽然我可以让另 让我们说,我需要与一个提供协议的类进行通信,并在 *** 作完成时调用委托方法,如下所示:

@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 – 如何简化回调逻辑与块?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1044572.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存