是否可以将完成块传递给Objective-C中的委托参数?

时间:2014-10-12 16:47:40

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

或者是否必须编写方法来接受块?换句话说,如果我们不控制定义方法的代码,我们是否可以使用代理,如果它是如何定义的,或者是否有办法传递两个匿名期望委托的方法调用中的函数(块)?

3 个答案:

答案 0 :(得分:6)

从技术上讲,答案是否定的,如果某些图书馆或班级与代表合作,可能有充分的理由,聪明而容易的事情就是使用它们。

如果出于某种原因,您真的对使用块感兴趣,因为它对您的问题域更自然,您可以实现一个包装器。

前方超级奇怪的例子。

例如,在UITableViewDataSource委托中,您有一个方法来获取每个部分中的行数:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

为了使用它,您必须将表dataSource属性设置为实现该方法的某个对象。通常的东西。

您可以创建一个数据源包装器来实现原始协议和您定义的新协议,以使用您想要的块接口。

typedef NSUInteger (^RowsCounterBlock)(NSInteger section);

@protocol RowsCounter
- (void)tableViewController:(id)controller countRowsWithBlock:(RowsCounterBlock)block;
@end

// we implement both the original protocol and our block based protocol
@interface ComplexDataSource : NSObject <UITableViewDataSource, RowsCounter>
{
    @property(strong) RowsCounterBlock counterBlock;
}

// save a block that knows how to count rows
- (void)tableViewController:(id)controller countRowsWithBlock:(RowsCounterBlock)block
{
    controller.dataSource = self;
    self.counterBlock = block;
}

// use the saved block to implement the method defined in the original delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (!self.counterBlock) return 0;
    return self.counterBlock(section);
}

@end

然后在你的表控制器中:

self.source = [ComplexDataSource new]; // save the data source in a property
[self.source tableViewController:self
              countRowsWithBlock:^NSUInteger(NSInteger section) {
              // this will be called each time the table view needs to ask
              // for the number of rows via the proxy delegate
              <#do your magic#>
              return <#rows#>;
}]

答案仍然是否定的,因为您正在使用原始委托......但是在幕后,您的主要界面现在是基于块的。

答案 1 :(得分:1)

简短的问题是否定的,如果定义方法来获取委托参数,如果你想使用一个块,那你就不走运了。

但是,正如其他人所说,有时委托模式比块更好,这一切都归结为用例。也许如果API设计者选择了委托而不是块,那么就有一个原因。

IMHO块在成功或失败回调时最有用,但在很多其他情况下,委托仍然更好(但是,我也喜欢使用匿名类,Java风格:)但是&# 39; s只是因为有时候我们会懒惰)

答案 2 :(得分:0)

首先,委托在许多情况下比使用闭包更好。在其他情况下,闭合更好。所以在一开始就应该问:为什么?

但是:定义调用闭包的委托方法有什么问题?