【问题标题】:iOS/Objective-C: How can I mix delegation and blocks?iOS/Objective-C:如何混合委托和块?
【发布时间】:2013-01-30 16:24:50
【问题描述】:

我有两节课。 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

探索的解决方案:

  • 按照this answer 中的建议,将Delegator 包装到新类或类别中并创建返回块的方法。这些解决方案有效,但过于复杂和耗时。

  • 使Blocker符合协议Delegate并将块保存在属性中,在方法@​​987654332@中实例化它,并在调用委托方法时调用块。这不起作用,因为没有指向这个新实例的强指针并且它被销毁了。

  • 在之前的解决方案中,为避免因缺少强指针而丢失实例,保留Blocker 的当前实例的静态数组,并在委托回调方法中删除它们。同样,此解决方案有效,但过于复杂。

【问题讨论】:

  • 我不确定在这种情况下您能否避免并发症。我会选择 3 号,如果实施得当,它应该是赢家。不要害怕复杂的事情:)
  • 不清楚您从-methodWithDelegate 返回的结果是什么,因为示例代码中的所有内容都返回void
  • 我不完全确定我是否理解了这个问题,但我很确定如果我理解了我可以帮助你。 Blocker 使用静态函数计算事物,然后通过块发送结果。您可以这样调用这些函数:[Blocker methodWithBlock:^(int result) { ... do anything with result ... }];,这似乎是什么问题?你失去了什么参考?
  • @Ismael:我正在尝试实现 methodWithBlock 方法。

标签: ios objective-c delegates objective-c-blocks


【解决方案1】:

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

【讨论】:

  • 是的。 Apple 似乎正朝着这个方向前进,以便在 NSOperationQueue 等对象中传达状态,并在您真正想要介入并更改/扩展功能而不使用子类化时保留委托。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多