集中我的 Objective C 应用程序的网络代码

发布于 2024-08-18 06:55:58 字数 662 浏览 5 评论 0原文

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

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

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

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

这两种方法都应该有效,但它们看起来都需要付出巨大的努力才能让 ServerRequest 唤醒调用代码并向其传递一个对象。我认为通知更加灵活,不那么痛苦,并且不太可能导致崩溃,但我对这两种方法都不太满意。任何反馈将不胜感激。谢谢。

I am trying to centralize my app's networking code. Basically, in any of the various places that need information from a server, I create an object serverRequest of my class ServerRequest to get the information. When ServerRequest is done, it needs to send the information back to the calling object. Of course it should work asynchronously -- I don't want my app to grind to a halt while it is waiting.

This return of the information is the tricky part. It seems my options are delegation and notification. As far as I can tell, they both have their issues:

DELEGATION:
I pass myself off as a delegate to the serverRequest object. The problem is that if I am deallocated before the request completes, serverRequest will be messaging a deallocated object and my program will crash. To prevent this, I would have to keep track of all my server requests (there might be more than one) and let them all know in my dealloc method so that I don't get any more messages. All of this is possible, but it sure seems like a pain.

NOTIFICATION:
Seems like a lot of work to pass the information around. I have to add myself as an observer to the notification center, then remove myself when I deallocate. Furthermore, I have to pass into ServerRequest the information of what kind of notification to post when it is done. And I ServerRequest has to shove the received data into an NSDictionary, which I then get it back out of after it is passed.

Both methods ought to work, but they both seem like an awful lot of effort just to have ServerRequest wake up the calling code and pass it an object. I am thinking notification is a bit more flexible, a bit less of a pain, and a bit less likely to cause a crash, but I'm not really happy with either approach. Any feedback would be appreciated. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蹲在坟头点根烟 2024-08-25 06:55:58

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

此外,某人必须拥有您的对象。在手动管理的内存中,ObjC 对象可以保留自身,但如果您想转向 GC,拥有数组是比 CFRetaining 自由浮动对象更干净的解决方案。

I would go with the list approach. Just have a requestController containing an NSMutableArray that keeps track of all the requests. The advantage of this is that, when your controller gets deallocated, you can do something like [requests makeObjectsPerformSelector: @selector(cancelRequest)] to stop all those requests from hogging the network. It also helps in debugging, because you can actually ask each object what requests it has pending, gauge the performance impact of many pending requests etc. When a request finishes, the request controller can be informed and can remove it from its list with a simple removeObject.

Also, someone has to own your objects. In manually managed memory, ObjC objects can retain themselves, but if you ever want to move to GC, having an array is a much cleaner solution than CFRetaining free-floating objects.

记忆之渊 2024-08-25 06:55:58

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

You should not be retaining your delegates. see Checking for a valid delegate object before sending it a message

雨轻弹 2024-08-25 06:55:58

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

例如,

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

you can retain the delegate passed in and you would then not be de-allocated until the server request is also finished.

e.g.

@interface ServerRequest : NSObject
{
  id delegate;
}

@property (retain) id delegate;
@end

@implementation ServerRequest
@synthesize delegate;
@end

But then you need to avoid releasing the ServerRequest from the other end, or you can make the initiator of the ServerRequest release it when it is itself released and that would take away the problem. To do that

@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
}
っ左 2024-08-25 06:55:58

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

我选择将请求(即实际内容)与交付系统分开。在您的情况下,这意味着 serverRequest 保存内容服务器请求的委托将是一个单例 CommLayer 类,它实际上负责发送请求、接收请求并通知委托。因此

,要发送 serverRequest,您需要调用类似 [CommLayer sendRequest:serverRequest withDelegate:myDelegate] 的内容。

现在,CommLayer 是保存委托的实际类,而不是 serverRequest,并且您始终可以通知 CommLayer 您的类。 东西不再有效

类的

  • 使用诸如 [CommLayer removeDelegate:myDelegate]之 您可以决定一次需要多少个打开的连接并对请求进行排队。
  • 您可以取消不需要的请求

I encountered similar problems in the past, but chose a slightly different design (similar to what @uliwitness suggested.

I choose to separate the request (i.e. the actual content) from the delivery system. In your case that would mean the serverRequest holds the content of the request (URL, data, etc.) but doesn't do the actual communication with the server. The delegate for the server request would be a singleton CommLayer class which will actually take care of sending the request, receiving it and notifying delegates about request completion.

So to send a serverRequest you would do call something like [CommLayer sendRequest:serverRequest withDelegate:myDelegate].

Now the CommLayer is the actual class that holds the delegate not the serverRequest, and you can always notify the CommLayer that your class is not valid anymore using something like [CommLayer removeDelegate:myDelegate]

Sure it's more work, but you really get a lot of benefits from this design, to name a few:

  • Real management of network traffic. You can decide how many open connection you want at once and queue requests.
  • You can cancel unneeded requests
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文