2

我有两节课。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并在委托回调方法中删除它们。同样,此解决方案有效,但过于复杂。

4

2 回答 2

0

使用可观察属性来传达结果,而不是委托和块属性。它更干净(也更容易),因为工作对象不必担心谁可能在看它。并且观察对象不必担心符合任何特殊协议。

于 2013-01-30T16:31:49.913 回答
0

优雅而简单的解决方案是只为您添加一个基于块的方法Delegator(例如通过一个类别)。我知道你说过你不能这样做,但是我们必须承认,任何其他基于块的解决方案,你正在创建新类以产生你想要的效果,但都没有通过优雅测试。

话虽如此,如果您迫切需要基于块的方法并且无法扩展Delegator,那么我会倾向于选项 2,除了创建这些类方法,将它们创建为实例方法,并Blocker实例化Delegator和定义包装器方法,以便类已经使用Delegator现在可以使用Blocker,但使用completion块而不是委托回调。而之前实例化的类Delegator现在可以实例化Blocker了。

于 2013-01-30T16:50:58.987 回答