NSURLConnection не запускается

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

Я создал новый проект (инструмент Foundation), который запускается из основного файла. Я установил делегат NSURLConnection на себя и реализовал необходимые методы делегата. Проблема в том, что эти методы никогда не вызываются. Неважно, поменяю ли я URL-адрес на какой-нибудь поддельный (как в примере ниже). Мне кажется, что приложение завершает запуск, не отправляя и не дожидаясь ответа. Может быть, мое приложение создает поток для запроса, а затем завершает работу, не дожидаясь ответа? Я знаю, что класс запущен, поскольку я получаю операторы NSLOG, такие как «Созданное соединение», но не получаю операторов NSLOG из методов делегата.

Что мне не хватает?

#import "NetworkController.h"
@implementation NetworkController

- (id)init
{
    if(self = [super init])
    {

    }   
    return self;
}
- (void)dealloc
{
    NSLog(@"Calling dealloc");
    [super dealloc];
}
- (void) performConnection
{
    NSMutableData *receivedData;
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:
                                       @"http://www.test.php?some variables"]];

    NSMutableURLRequest *connectionRequest = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
    [url release];
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:connectionRequest delegate:self startImmediately:YES];

    if (!theConnection)
    {
        NSLog(@"Failed to submit request");
    }
    if(theConnection)
    {
        receivedData=[[NSMutableData data] retain];
        NSLog(@"Created connection.");

        NSLog(@"--------- Request submitted ---------");
        NSLog(@"receivedData: %@", receivedData);
    }

    [connectionRequest release];
}

#pragma mark NetworkController Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"Received response: %@", response);
    NSLog(@"Received response, connection retain count is %d",[connection retainCount]);
}

#pragma mark NetworkController Delegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"Connection received data, retain count: %d", [connection retainCount]);
}

#pragma mark NetworkController Delegate
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"finished connection retain count:  %d", [connection retainCount]);}

#pragma mark NetworkController Delegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Error receiving response: %@", error);
    [connection release];
}

@end

#import <Foundation/Foundation.h>
#import "NetworkController.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


    NetworkController *n = [[NetworkController alloc] init];
    n.performConnection;
    [n release];

    // insert code here...
    NSLog(@"Hello, World!");
    [pool drain];
    return 0;
}

person Community    schedule 10.05.2009    source источник
comment
Не могли бы вы опубликовать свою основную функцию? Тот, где вы создаете экземпляр NetworkManager.   -  person Pablo Santa Cruz    schedule 10.05.2009
comment
То же, что говорит Пабло, но я почти уверен, что вы не запускаете свой цикл выполнения ...   -  person Jason Coco    schedule 10.05.2009
comment
Моя основная функция выглядит так: #import ‹Foundation / Foundation.h› #import NetworkController.h int main (int argc, const char * argv []) {NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NetworkController * n = [[выделение NetworkController] инициализация]; n.performConnection; [n релиз]; // вставляем сюда код ... NSLog (@Hello, World!); [слив из бассейна]; возврат 0; }   -  person    schedule 10.05.2009
comment
добавлена ​​основная функция к вопросу.   -  person    schedule 10.05.2009


Ответы (1)


Во-первых, синтаксис сообщения:

[n performConnection];

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

В любом случае основная проблема заключается в том, что вы используете асинхронный API NSURLConnection (хорошо), но ожидаете синхронного поведения (плохо). Все методы NSURLConnection немедленно возвращаются, а затем работают в фоновом режиме, с идеей отправки делегированных сообщений вашему сетевому контроллеру по мере того, как что-то происходит, но сразу после того, как вы закончите все настройки, вы отпускаете сетевой контроллер (в свою очередь, утечка соединения, поскольку вы не release это в вашем dealloc методе), затем выйдите.

Вам необходимо запустить цикл выполнения перед тем, как освободить сетевой контроллер, чтобы дать время соединения для отправки запроса, чтения ответа и отправки сетевому контроллеру некоторых делегированных сообщений. Вам также необходимо cancel и release соединение в dealloc методе сетевого контроллера.

Кроме того, вам необходимо сделать эту переменную NSMutableData переменной экземпляра, поскольку вам нужно иметь возможность обращаться к ней из методов делегата. Не забудьте также отпустить это в своем dealloc методе (и release его и установить nil в обоих методах делегата, которые указывают на то, что соединение завершено).

person Peter Hosey    schedule 10.05.2009
comment
+1, это лучше моего ответа. Кроме того, мы должны сказать ему, чтобы он не обезвреживал main вручную, если он не знает, что делает. - person zoul; 10.05.2009
comment
Он пишет инструмент командной строки; размещение хоть какого-то кода в main - нормально для такой программы. - person Peter Hosey; 10.05.2009
comment
Ага, это мне не пришло в голову. - person zoul; 10.05.2009
comment
Ты прав, Питер, соединение действительно считается входным источником. Я помню, что он не работал должным образом в 10.4 tho, так что, возможно, он был изменен. В любом случае, я удаляю свой ответ, потому что я недостаточно внимательно прочитал его код, и в нем много проблем, которые, как мне кажется, решаются в вашем ответе. - person Jason Coco; 10.05.2009