第二个异步NSURLConnection不调用委托方法

时间:2011-04-20 01:20:00

标签: iphone objective-c delegates nsurlconnection nsurlrequest

从我的ApplicationDelegate,我正在通过网络进行NSURLConnection获取(它包含在一个类中,如下所示)。这个似乎工作正常:我得到didReceiveData中的所有数据,我得到完成调用connectionDidFinishLoading。在connectionDidFinishLoading结束时,我实例化一个或多个稍微不同的包装类,但它们基本上是相同的。问题是第二个NSURLConnection的委托从来没有调用它的方法。

我看过many different answers,但都无济于事。我没有产生任何新线程和所有[NSThread isMainThread]检查我在整个代码中乱丢了返回true。

我很难过。谁能帮我吗?这是相关的代码:

App Delegate:

- (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     {         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)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 个答案:

答案 0 :(得分:1)

我认为问题在于您在-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发送到{{1}无论如何。此外,您应该保留传递给初始化程序的self对象。

以下更有意义:

url

不要忘记在-(id)initWithParams:(id<ConnectionWrapperDelegate>)d url:(NSURL*)url { self = [super init]; if (self) { delegate = d; connURL = [url retain]; } return self; } 中发布url对象,或者在为-dealloc分配其他值时。

答案 1 :(得分:1)

一些事情:我没有看到didFailWithError:在你的第一个包装器类中,并且(有点偏离主题)你是否在使用DifferentConnectionWrapper * w泄漏内存?

无论如何,我要尝试的是:看看你是否可以直接从appDelegate而不是ConnectionWrapper调用DifferentConnectionWrapper。  我会尝试在任何情况下解耦这两个电话。当第一个完成并调用appDelegate时,你不能从那里启动你的DifferentConnectionWrapper吗?

我意识到这并不能解释你的问题,但你可能会让它发挥作用(这两件事中哪一件更重要,是一场完全不同的辩论。)

答案 2 :(得分:0)

行。事实证明,这个错误是由我错过的东西引起的。在第二次请求之后,我正在进行一次艰难的旋转,这可能会搞砸任何事情。一旦我解决了这个问题,一切都运转正常。

感谢您的帮助。