2010-01-16 66 views
1

我试图集中我的应用程序的网络代码。基本上,在任何需要从服务器获取信息的地方,我创建一个对象serverRequest来获取信息。当ServerRequest完成时,它需要将信息发回给调用对象。当然,它应该异步工作 - 我不希望我的应用程序在等待时停下来。集中我的目标C应用程序的网络代码

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

代表: 我把自己作为一个代理传递给serverRequest对象。问题是,如果我在请求完成之前解除分配,那么serverRequest将传递一个释放对象,并且我的程序将崩溃。为了防止这种情况发生,我将不得不跟踪所有服务器请求(可能有多个请求),并让我们在我的dealloc方法中知道所有请求,以便我不会再收到任何消息。所有这些都是可能的,但它确实看起来像一个痛苦。

通知: 似乎有很多工作要传递信息。我必须将自己添加为通知中心的观察员,然后在我释放时删除自己。此外,我必须在ServerRequest中传递完成后发布什么样的通知的信息。我的ServerRequest必须将接收到的数据推送到NSDictionary中,然后在传递之后将其返回。

这两种方法都应该可以工作,但它们看起来像是一个非常大的努力,只是让ServerRequest唤醒调用代码并将它传递给一个对象。我认为通知有点更灵活,更少一点痛苦,导致崩溃的可能性更小,但我对这两种方法都不满意。对于任何反馈,我们都表示感谢。谢谢。

回答

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 
} 
1

我会去列表方法。只需要一个包含NSMutableArray的requestController来跟踪所有的请求。这样做的好处是,当你的控制器被解除分配时,你可以做一些事情,如[请求makeObjectsPerformSelector:@selector(cancelRequest)],以阻止所有这些请求使网络被占用。它还有助于调试,因为实际上您可以询问每个对象哪些请求有待处理,衡量许多未决请求的性能影响等。请求完成后,可以通知请求控制器,并可以通过简单的方式将其从列表中删除的removeObject。

另外,有人必须拥有你的对象。在手动管理的内存中,ObjC对象可以保留它们自己,但是如果你想要移动到GC,拥有一个数组是一个比CFRaining free-floating objects更清洁的解决方案。

0

过去我遇到过类似的问题,但选择了一个略有不同的设计(类似于@uliwitness的建议。

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

所以要发送一个serverRequest,你会打电话给[CommLayer sendRequest:serverRequest withDelegate:myDelegate]。

现在CommLayer是保存委托不serverRequest实际的类,你可以随时通知CommLayer您的类不再有效使用类似[CommLayer removeDelegate:myDelegate]

当然这更多的工作,但你真的从这个设计中得到很多好处,例如:

  • 网络流量的真正管理。您可以决定一次打开多少个连接并排队请求。
  • 您可以取消不需要的请求
相关问题