Objective-C多个回调到同一个函数

时间:2014-07-09 06:39:14

标签: ios objective-c callback delegates

现在我有一个处理大量网络请求的视图控制器。它们都是NetworkRequest类的子类,这个视图控制器是所有类的委托。它实现了一个回调函数networkRequestDidFinish

问题是所有这些网络请求都是单独的对象,它们都会调用同一个函数。设计这个的正确方法是什么?现在我在networkRequestDidFinish中查看一堆if语句,看看返回了哪种网络请求。虽然感觉不对,但我不确定在这种情况下常规做什么。

感谢。

2 个答案:

答案 0 :(得分:0)

这里有一个有用的模式是确保委托方法将self传递给视图控制器。听起来你可能已经这样做了 - 如果你使用了一系列if语句,你可能会指向相关的NetworkRequest。如果您不是,或者不确定,请继续阅读。

在使用委派的任何地方,您都会看到这种模式。作为一个任意的例子,取UITableViewDelegate protocol。每个委托方法的第一个参数是UITableView。例如:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

UITableView实例调用此委托方法时,它会传递self作为第一个参数。它的确如下:

[self.delegate tableView:self heightForRowAtIndexPath:0];

然后,委托知道它正在处理哪个 UITableView,因为它有一个指针掉落在其腿上,作为参数tableView

在您的情况下,我首先将一个参数添加到委托方法networkRequestDidFinish,将其签名更改为:

- (void)networkRequestDidFinish:(NetworkRequest *)networkRequest

通过这种方式,您可以告诉 NetworkRequest的哪个实例已调用委托方法。


已经有了,或者那还不够好?好吧,接下来我要说的是考虑你是否真的需要根据调用委托方法的NetworkRequest实例的实际类来执行不同的操作。如果您只是传递数据,答案可能是否定的。例如:

- (void)networkRequestDidFinish:(NetworkRequest *)networkRequest {
    [self processData:networkRequest.data];
}

该方法并不关心类networkRequest究竟是什么。但你似乎很在乎,因为你正在做“一堆if陈述。”然后我会说让他们都按一个委托方法可能是一个错误。相反,您可能希望删除NetworkRequest上的委托,而是将协议添加到该类的每个子类,特定于子类。

什么?

让我们看一个例子。

想象一下,NetworkRequest的一个子类是FooNetworkRequest,当然,它要求foos。它的标题可能如下所示:

// stuff...
@protocol FooNetworkRequestDelegate
- (void)fooNetworkRequestDidFinish:(FooNetworkRequest *)fooNetworkRequest;
@end

@interface FooNetworkRequest : NetworkRequest
@property (weak, nonatomic) id<FooNetworkRequestDelegate> delegate;
// stuff...
@end

您对NetworkRequest的所有其他子类应用了类似的处理方法。然后,您的视图控制器将采用这些协议中的每一个,并为NetworkRequest的每个子类使用单独的方法。


那似乎仍然有点脏,对吧?它对我有用。也许这是一个提示,你的视图控制器试图同时处理太多的事情。您应该考虑尝试将所有这些NetworkRequest子类的责任分散到多个视图控制器或模型类。

如果这不是一个选项,您至少可以通过使用一个或多个类别使您的视图控制器的源更容易阅读。像往常一样,将视图控制器的主要行为放在其.m文件中,然后在该视图控制器上创建一个采用适当协议并处理请求的类别。

答案 1 :(得分:0)

通常有2个不错的程序。

  1. 您可以使用block而不是委托。这意味着您可以在实例化或发出请求时向您的请求类发送一个块。
  2. 使用目标/选择器对系统使其看起来有点像向UIButton添加目标。 NSInvocation应该做到这一点。