централизация сетевого кода моего целевого приложения C - PullRequest
1 голос
/ 17 января 2010

Я пытаюсь централизовать сетевой код моего приложения.По сути, в любом из различных мест, где требуется информация от сервера, я создаю объект serverRequest моего класса ServerRequest для получения информации.Когда ServerRequest завершен, он должен отправить информацию обратно вызывающему объекту.Конечно, это должно работать асинхронно - я не хочу, чтобы мое приложение останавливалось, пока оно ждет.

Этот возврат информации - сложная часть.Кажется, мои варианты делегирования и уведомления.Насколько я могу судить, у них обоих есть свои проблемы:

ДЕЛЕГАЦИЯ: я выдавал себя за делегата объекта serverRequest.Проблема заключается в том, что если я освобождаюсь до завершения запроса, serverRequest будет отправлять сообщения об освобожденном объекте, и моя программа аварийно завершит работу.Чтобы предотвратить это, мне нужно было бы отслеживать все мои запросы к серверу (их может быть больше одного) и сообщать их всем в моем методе dealloc, чтобы я больше не получал сообщений.Все это возможно, но это, конечно, похоже на боль.

УВЕДОМЛЕНИЕ: Похоже, много работы для передачи информации.Я должен добавить себя в качестве наблюдателя в центр уведомлений, а затем удалить себя при освобождении.Кроме того, я должен передать в ServerRequest информацию о том, какие уведомления отправлять, когда это будет сделано.И мне ServerRequest нужно запихнуть полученные данные в NSDictionary, из которого я затем получаю их обратно после их передачи.

Оба метода должны работать, но они оба кажутся огромными усилиями только для того, чтобыпопросите ServerRequest разбудить вызывающий код и передать ему объект.Я думаю, что уведомление немного более гибкое, немного менее болезненное и немного менее вероятное, чтобы вызвать сбой, но я не очень доволен любым подходом.Любая обратная связь будет оценена.Спасибо.

Ответы [ 4 ]

1 голос
/ 17 января 2010

Я бы пошел с подходом списка.Просто имейте requestController, содержащий NSMutableArray, который отслеживает все запросы.Преимущество этого состоит в том, что, когда ваш контроллер освобождается, вы можете сделать что-то вроде [запросы makeObjectsPerformSelector: @selector (cancelRequest)], чтобы все эти запросы не блокировали сеть.Это также помогает в отладке, потому что вы можете фактически спросить каждый объект, какие запросы он ожидает, измерить влияние на производительность многих ожидающих запросов и т. Д. Когда запрос завершается, контроллер запроса может быть проинформирован и может удалить его из своего списка с помощью простогоremoveObject.

Кроме того, кто-то должен владеть вашими объектами.В управляемой вручную памяти объекты ObjC могут сохранять себя, но если вы когда-нибудь захотите перейти в GC, наличие массива является гораздо более чистым решением, чем CFReservation свободно плавающих объектов.

0 голосов
/ 18 января 2010

В прошлом я сталкивался с похожими проблемами, но выбрал немного другой дизайн (аналогично тому, что предлагал @uliwitness.

Я предпочитаю отделить запрос (т.е. фактический контент) от системы доставки. В вашем случае это будет означать, что serverRequest содержит содержимое запроса (URL, данные и т. Д.), Но не осуществляет фактическую связь с сервером. Делегатом для запроса к серверу будет одноэлементный класс CommLayer, который фактически позаботится об отправке запроса, его получении и уведомлении делегатов о завершении запроса.

Таким образом, для отправки запроса на сервер вы должны вызвать что-то вроде [CommLayer sendRequest: serverRequest withDelegate: myDelegate].

Теперь CommLayer является фактическим классом, который содержит делегат, а не serverRequest, и вы всегда можете уведомить CommLayer о том, что ваш класс больше не является допустимым, используя что-то вроде [CommLayer removeDelegate: myDelegate]

Конечно, это больше работы, но вы действительно получаете много преимуществ от этого дизайна, чтобы назвать несколько:

  • Реальное управление сетевым трафиком. Вы можете решить, сколько открытых соединений вы хотите, и очереди запросов.
  • Вы можете отменить ненужные запросы
0 голосов
/ 17 января 2010
0 голосов
/ 17 января 2010

вы можете сохранить переданный делегат, и тогда вы не будете отменены, пока запрос сервера также не будет завершен.

, например

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