iPhone SDK: размещение NSData с NSMutableURLRequest приводит к таинственному падению - PullRequest
8 голосов
/ 10 марта 2009

Я вижу сбой, который происходит через 10 или 20 секунд после того, как выполненный мной POST-запрос (didReceiveResponse, didReceiveData и connectionDidFinishLoading все срабатывает задолго до сбоя).

Это код, который я использую для запроса:

NSURL* url = [[NSURL alloc] initWithString:urlString];
[urlString release];

NSData* requestData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:@"%d", [requestData length]];

NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:requestData];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:requestDataLengthString forHTTPHeaderField:@"Content-Length"];
[request setTimeoutInterval:30.0];
[url release];
[requestData release];
[requestDataLengthString release];

m_URLConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];  
[request release];

Что очень странно в этом сбое, так это: если я не вызываю setHTTPBody с моим NSData объектом, setValue:@"application/json" для Content-Type и setValue:requestDataLengthString для Content-Length, сбой вызывает не случается. Я полностью озадачен тем, что происходит. Насколько я могу судить, сбой напрямую связан с отправкой объекта NSData с моим запросом. Когда происходит сбой, верхние элементы в стеке вызовов для сбоя (EXEC_BAD_ACCESS) следующие:

  • objc_msgSend
  • CFRelease
  • HTTPMessage::~HTTPMessage
  • _CFRelease
  • HTTPWriteFilter::~HTTPWriteFilter

Может кто-нибудь придумать, что я могу делать неправильно? Я в полном недоумении из-за того, что я делаю неправильно, как это исправить или как обойти это. Есть ли лучший способ POST-данных, чем тот, который я делаю?

Ответы [ 3 ]

7 голосов
/ 10 марта 2009

Вы правы в том, что проблема связана с вашим NSData объектом. Вы распределяете это так:

NSData* requestData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];

В соответствии с правилами, изложенными в Руководстве по программированию управления памятью для какао , вы не являетесь владельцем данных, поэтому вам не следует в дальнейшем вызывать release. dataUsingEncoding вызывает autorelease, поэтому объект будет release d в следующий раз, когда пул авто-релиза опустошится. Поскольку вы добавляете дополнительный release, пул автоматического выпуска попытается release объект, который уже был освобожден, что вызывает сбой.

5 голосов
/ 10 марта 2009

Вы выпустили автоматически выпущенный объект.

Удалить строку [releaseData release]; Тебе это не нужно. Это приводит к сбою, поскольку данные передаются вами, а затем снова высвобождаются после завершения отправки данных, что является слишком большим количеством выпусков.

Как правило, вы не вызываете release для объекта, пока вы не выделите его, или документы прямо не сообщат, что возвращаемый объект не высвобождается автоматически. (что редко).

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

Я не знаю, есть ли лучший способ размещения данных - у вас код выглядит нормально, за исключением того, что данные json, вероятно, дублируются как в строке, так и в объекте данных, но в объеме отправляемых данных. может быть маленьким Если это не так, вы должны выпустить строку jsonData сразу после создания данных. (Это будет означать, что строка jsonData должна быть из вызова alloc / init вместе с данными). Или не создавайте jsonData как строку, просто сделайте его неизменяемым с самого начала, но это может быть неудобно.

- Том

1 голос
/ 10 марта 2009

Проверьте звонок на [urlString release]; тоже. если urlString был создан с чем-то вроде stringWithFormat или stringwithString, вы не должны выпускать его.

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