1

我正在尝试集中我的应用程序的网络代码。基本上,在任何需要来自服务器的信息的地方,我都会创建我的类 ServerRequest 的对象 serverRequest 来获取信息。ServerRequest 完成后,需要将信息发送回调用对象。当然它应该异步工作——我不希望我的应用程序在等待时停止。

信息的返回是棘手的部分。看来我的选择是授权和通知。据我所知,他们都有自己的问题:

委托:我将自己作为 serverRequest 对象的委托。问题是,如果我在请求完成之前被释放,serverRequest 将发送一个已释放对象的消息,我的程序将崩溃。为了防止这种情况,我必须跟踪我的所有服务器请求(可能不止一个),并在我的 dealloc 方法中让它们都知道,这样我就不会再收到任何消息了。这一切都是可能的,但它确实看起来很痛苦。

通知:传递信息似乎需要做很多工作。我必须将自己添加为通知中心的观察者,然后在我解除分配时删除自己。此外,我必须将完成后发布哪种通知的信息传递给 ServerRequest。我的 ServerRequest 必须将接收到的数据推送到一个 NSDictionary 中,然后我在它通过后将其取回。

这两种方法都应该可以工作,但它们似乎都需要付出很多努力才能让 ServerRequest 唤醒调用代码并将其传递给一个对象。我认为通知更灵活一点,痛苦少一点,导致崩溃的可能性更小,但我对这两种方法都不满意。对于任何反馈,我们都表示感谢。谢谢。

4

4 回答 4

1

我会采用列表方法。只需一个 requestController 包含一个 NSMutableArray 来跟踪所有请求。这样做的好处是,当您的控制器被释放时,您可以执行类似 [requests makeObjectsPerformSelector: @selector(cancelRequest)] 的操作来阻止所有这些请求占用网络。它还有助于调试,因为您实际上可以询问每个对象它有哪些未决请求,评估许多未决请求的性能影响等。当请求完成时,可以通知请求控制器并可以通过简单的操作将其从列表中删除删除对象。

此外,必须有人拥有您的物品。在手动管理的内存中,ObjC 对象可以保留自己,但如果您想迁移到 GC,拥有一个数组是比 CFRetaining 自由浮动对象更清洁的解决方案。

于 2010-01-17T14:16:26.517 回答
0

我过去也遇到过类似的问题,但选择了稍微不同的设计(类似于@uliwitness 的建议。

我选择将请求(即实际内容)与交付系统分开。在您的情况下,这意味着 serverRequest 包含请求的内容(URL、数据等),但不与服务器进行实际通信。服务器请求的委托将是一个单例 CommLayer 类,它实际上将负责发送请求、接收请求并通知委托完成请求。

因此,要发送 serverRequest,您需要调用类似 [CommLayer sendRequest:serverRequest withDelegate:myDelegate] 的方法。

现在 CommLayer 是持有委托而不是 serverRequest 的实际类,您始终可以使用 [CommLayer removeDelegate:myDelegate] 之类的方法通知 CommLayer 您的类不再有效

当然这是更多的工作,但你真的从这种设计中获得了很多好处,仅举几例:

  • 网络流量的真实管理。您可以决定一次需要多少个打开的连接并将请求排队。
  • 您可以取消不需要的请求
于 2010-01-18T10:30:13.467 回答
0

您可以保留传入的委托,然后在服务器请求也完成之前不会取消分配。

例如

@interface ServerRequest : NSObject
{
  id delegate;
}

@property (retain) id delegate;
@end

@implementation ServerRequest
@synthesize delegate;
@end

但是你需要避免从另一端释放 ServerRequest,或者你可以让 ServerRequest 的发起者在它本身被释放时释放它,这样就可以解决问题。要做到这一点

@interface SomeObject : NSObject
{
  ServerRequest getsomedata;
}

@property (retain) ServerRequest getsomedata;
@end

- (void)f()
{
  [self setGetsomedata:[[ServerRequest alloc] init]];
  [[self getsomedata] release]; // take away the refcount from allocating, setting the property will retain
}
于 2010-01-16T23:07:27.183 回答
0

你不应该保留你的代表。请参阅在发送消息之前检查有效的委托对象

于 2010-01-16T23:11:29.673 回答