Второй асинхронный NSURLConnection не вызывает методы делегата - PullRequest
0 голосов
/ 20 апреля 2011

Из моего ApplicationDelegate я делаю выборку NSURLConnection по сети (она заключена в класс, как вы увидите ниже).Кажется, что этот работает правильно: я получаю все данные в didReceiveData, и я получаю вызов завершения connectionDidFinishLoading.В конце connectionDidFinishLoading я создаю один или несколько классов-оболочек немного другого типа, но по сути это одно и то же.Проблема в том, что у второго делегата NSURLConnection никогда не вызывались его методы.

Я смотрел на много разных ответов , но всено безрезультатно.Я не создаю никаких новых потоков, и все проверки [NSThread isMainThread], которые я засорял в коде, возвращают true.

Я в замешательстве.Может кто-нибудь мне помочь?Вот соответствующий код:

Делегат приложения:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    ConnectionWrapper* w = [[ConnectionWrapper alloc] initWithParams:self
    url:[NSURL URLWithString:<url>]];
[w beginFetch];

    return YES;
}

...

-(void)fetchCompleted:(NSURL*)url directory:(NSString*)directory
{
NSLog(@"fetch completed");
}

-(void)fetchFailed:(NSURL*)url
{
NSLog(@"fetch failed");
}

...

ConnectionWrapper:

-(id)initWithParams:(id<ConnectionWrapperDelegate>)d url:(NSURL*)url
{
    delegate = d;

    connURL = url;

    return [self init];
}

-(void)beginFetch
{
    NSURLRequest* request = [[NSURLRequest alloc] initWithURL:connURL];
    NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [conn release];
    [request release];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"append");
    [responseData appendData:data];
}

- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
    ... parsing ....

    DifferentConnectionWrapper* w = [[DifferentConnectionWrapper alloc] initWithParams:self
        url:[NSURL URLWithString:<different url>]];
    [w beginFetch];
}

-(void)fetchCompleted:(NSURL*)URL
{
    NSLog(@"completed: %@", URL);
}

-(void)fetchFailed:(NSURL*)URL
{
    NSLog(@"failed");
}

DifferentConnectionWrapper:

- (id) initWithParams: (id) d url: (NSURL *) url {делегат = d;

    connURL = url;

    return [self init];
}

-(void)beginFetch
{
    NSURLRequest* request = [[NSURLRequest alloc] initWithURL:connURL];
    NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [conn release];
    [request release];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"append");
    [responseData appendData:data];
}

- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
    ... parsing ....

    DifferentConnectionWrapper* w = [[DifferentConnectionWrapper alloc] initWithParams:self
        url:[NSURL URLWithString:<different url>]];
    [w beginFetch];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"got response");
    [responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"got data");
    [responseData appendData:data];
}

- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
    NSLog(@"image saver completed: %@", connURL);
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"error");
}

ConnectionWrapper и DifferentConnectionWrapper имеют схожие функции, но есть другая логика, которую я здесь опущил для краткости.за помощь.Я ценю это.

Ответы [ 3 ]

1 голос
/ 20 апреля 2011

Пара вещей: я не вижу didFailWithError: в вашем первом классе-обертке, и (немного не по теме) вы теряете память с вашим DifferentConnectionWrapper * w?

В любом случае, я бы попробовал: посмотрите, можете ли вы вызывать DifferentConnectionWrapper непосредственно из appDelegate вместо ConnectionWrapper. И я бы попытался отделить два вызова в любом случае. Когда первый завершается и вызывает appDelegate, вы не можете запустить свой DifferentConnectionWrapper оттуда?

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

1 голос
/ 20 апреля 2011

Я считаю, что проблема в том, что вы освобождаете соединение URL в -beginFetch:

-(void)beginFetch
{
    NSURLRequest* request = [[NSURLRequest alloc] initWithURL:connURL];
    NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [conn release];
    [request release];
}

Объект URL-соединения должен оставаться активным и освобождаться после завершения загрузки соединения:

- (void) connectionDidFinishLoading: (NSURLConnection*) connection
{
    ... parsing ....

    // *** Release the connection and whatever data you’ve kept related to
    // this particular connection
    [connection release];
    [responseData release];
    // *** or [responseData setLenght:0]; depending on how you’re
    // managing responseData

    DifferentConnectionWrapper* w = [[DifferentConnectionWrapper alloc] initWithParams:self
        url:[NSURL URLWithString:<different url>]];
    [w beginFetch];
}

или когда произошла ошибка:

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error
{
    // *** Release the connection and whatever data you’ve kept related to
    // this particular connection
    [connection release];
    [responseData release];
    // *** or [responseData setLenght:0]; depending on how you’re
    // managing responseData

    // inform the user
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
<Ч />

Редактировать: Ваш инициализатор немного странный:

-(id)initWithParams:(id<ConnectionWrapperDelegate>)d url:(NSURL*)url
{
    delegate = d;    
    connURL = url;
    return [self init];
}

Невозможно узнать, что происходит, если мы не увидим код для -init и, во всяком случае, это должен быть назначенный инициализатор, поэтому он не должен отправлять -init на self в любом случае. Кроме того, вы должны сохранить объект url, который передается инициализатору.

Имеет смысл следующее:

-(id)initWithParams:(id<ConnectionWrapperDelegate>)d url:(NSURL*)url
{
    self = [super init];
    if (self) {
        delegate = d;    
        connURL = [url retain];
    }
    return self;
}

Не забудьте освободить объект url в -dealloc или при назначении другого значения для connURL.

0 голосов
/ 21 апреля 2011

OK.Оказывается, эта ошибка была вызвана чем-то, что я пропустил.Сразу после этого второго запроса у меня начался сильный спор, который, вероятно, облажался почти что угодно.Как только я исправил эту проблему, все заработало просто отлично.

Спасибо за помощь.

...