Мое приложение отправляет много сообщений через HTTP
запросов. Я написал простую обертку вокруг HTTP-запроса, у которого есть первичный метод, чтобы отменить запрос и вернуть результат NSData
.ARC Async Block Best Practices
Это выглядит следующим образом:
- (void)sendRequest:(NSURLRequest *)request {
[[[NSURLSession sharedSession] dataTaskWithRequest:request
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSLog(@"---->> request returned");
if (_delegate == nil)
return;
if (error == nil) {
// forward along
[_delegate requestReturnedResult:data withResponse:response];
}
else {
// error occurred
[_delegate requestReturnedError:error withResponse:response];
}
}] resume];
}
Этот HttpRequestHelper
объект является ivar
из моего сообщения абстракции объекта OutboundMessage
, что упаковывает данные, а затем отправляет его.
У меня есть объект MessageSender
, который принимает некоторые данные, создает объект OutboundMessage
и отправляет его.
Эта абстракция работает хорошо, за исключением того, что я думаю, что сталкиваюсь с проблемой с ARC.
Когда кто-то звонит [MessageSender send:]
, I alloc
a OutboundMessage
и отправляет его.
То, что я вижу через NSLog
, что мой OutboundMessage
очищается (предположительно, когда send
выходит, то я вижу HttpRequestHelper
очищены. Тогда я вижу NSLog
в обработчике завершение моего dataTaskWithRequest
.
Это указывает на то, что все, что было у моего помощника запроса, было очищено до завершения HTTP-запроса. Затем, как вы можете себе представить, в ближайшее время я попытаюсь добавить свой ответ через delegate
, я получаю exc_bad_access
.
Я могу t hink некоторых творческих способов предотвратить освобождение и предотвратить это, но то, что я хотел бы знать, концептуально является лучшим практическим приемом для обработки этого шаблона при отключении сообщений, когда обертывающие объекты очищаются только после завершения запроса.
Спасибо.
Update Каждый объект обертка был использованием initWithDelegate:self
шаблонов стиля, и я заметил, эти делегаты были сохранены, как это:
@property (nonatomic, assign) id<HttpRequesterDelegate> delegate;
Я изменил к ним strong
и, кажется, чтобы исправить это, но я я не уверен, что сейчас я теряю память или если есть более оптимальный подход.
Изменение его на сильный, скорее всего, приведет к утечке памяти, если вы не установите делегат в нуль где-нибудь после того, как звонок вернется. – dan
Хм, так как я делаю 'initWithDelegate: self', было бы достаточно установить делегат на нуль в каждом' dealloc'? Каковы альтернативные решения этой проблемы? – Ternary
'OutboundMessage' является объектом' NSdata'? Как вы создаете объект 'request' из' OutboundMessage'? –