我有两节课。 Delegator
使用委托发送结果。 Blocker
在静态方法中使用块。
如果不更改Delegator
,我如何优雅且轻松地实施methodWithBlock
,以便使用methodWithDelegate
生成的结果调用块?
委托者:
@class Delegator;
@protocol Delegate <NSObject>
- (void)delegator:(Delegator *)sender producedResult:(int)result;
@end
@interface Delegator : NSObject
@property (weak, nonatomic) id <Delegate> delegate;
- (void)methodWithDelegate;
@end
@implementation Delegator
- (void)methodWithDelegate
{
// Some asynchronous computation resulting in
[self.delegate delegator:self producedResult:42];
}
@end
阻断剂:
@interface Blocker : NSObject
+ (void)methodWithBlock:(void(^)(int result))block;
@end
@implementation Blocker
+ (void)methodWithBlock:(void(^)(int result))block
{
// How to call Delegator's methodWithDelegate and return
// the result using block ?
...
}
@end
探索解决方案:
将Delegator
包装到新的类或类别中,并创建一个返回块的方法,如this answer中所述。这些解决方案有效,但过于复杂和耗时。
使Blocker
符合协议Delegate
并将块保留在属性中,在方法methodWithBlock
中实例化它,并在调用委托方法时调用块。这不起作用,因为没有强大的指针指向这个新实例并且它被破坏了。
在前面的解决方案中,为避免因缺少强指针而丢失实例,请保留当前Blocker
实例的静态数组,并在委托回调方法中删除它们。同样,这个解决方案有效,但太复杂了。
答案 0 :(得分:0)
使用可观察的属性来传达结果,而不是委托和阻止属性。它更干净(也更容易),因为工作对象不必担心谁可能正在观看它。观看对象不必担心符合任何特殊协议。
答案 1 :(得分:0)
优雅而简单的解决方案是只为您的Delegator
添加基于块的方法(例如通过类别)。我知道你说你不能这样做,但我们不得不承认,任何其他基于块的解决方案,你正在创建新的类来产生你想要的效果,都无法进行优雅测试。
话虽如此,如果你迫切需要基于块的方法并且无法扩展Delegator
,那么我将倾向于选项2,除了制作那些类方法,使它们成为实例方法,并且{{1} 1}}实例化Blocker
并定义包装器方法,以便使用Delegator
的类现在可以使用Delegator
,但使用Blocker
块而不是委托回调。以前实例化completion
的类现在可以实例化Delegator
。