关注URLConnection有什么问题?

时间:2009-04-01 16:30:56

标签: objective-c cocoa asynchronous nsurlconnection

另见:

  

Objective-C Asynchronous Web Request with Cookies

我花了一天时间编写这段代码,有人能告诉我这里有什么问题吗?

WSHelper继承自NSObject,我甚至尝试过NSDocument和NSObjectController以及所有内容。

-(void) loadUrl: (NSString*) urlStr{
    url = [[NSURL alloc] initWithString:urlStr];
    request = [NSURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];
    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    if(connection)
    {
        receivedData = [[NSMutableData data] retain];
            //[connection start];
    }
    else
    {       display error etc...   }
    NSApplication * app = [NSApplication sharedApplication];
    [app runModalForWindow: waitWindow];// <-- this is the problem...
}

-(void)connection: (NSURLConnection*)connection didReceiveData:(NSData*)data{
    progressText = @"Receiving Data...";
    [receivedData appendData:data];
}

-(void)connection: (NSURLConnection *)connection didFailWithError:(NSError *)error{
    progressText = @"Error...";
    NSAlert * alert = [[NSAlert alloc] init];
    [alert setMessageText:[error localizedDescription]];
    [alert runModal];
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    progressText = @"Done...";
    pData = [[NSData alloc] initWithData:receivedData];
    [self hideWindow];
}

代码不会做任何事情,它根本没有进展。我甚至尝试使用/不使用startImmediately:YES但没有运气!!!,这是在主窗口中执行的,所以即使是线程及其运行循环也能成功运行。

我试过调用同步请求,它工作正常!!但我需要异步解决方案。

我在项目中添加了CoreServices.Framework,还有什么我应该添加到项目中的吗?任何编译器设置?或者我必须在使用NSURLConnection之前初始化任何内容?

在自己的NSRunLoop,Objective-C和MAC Development上的不同线程上运行NSURLConnection的任何解决方案在文档中的任何地方都没有示例代码,这使得编写代码变得非常困难。

4 个答案:

答案 0 :(得分:4)

我也遇到了在模态窗口中使用NSURLConnection时没有调用委托方法的相同问题。

经过一些调查后,下面的代码解决了它。

NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:requst delegate:self startImmediately:NO];
[conn scheduleRunLoop:[NSRunLoop currentRunLoop] forMode:NSModalPanelRunLoopMode];
[conn start];

但是,当connectionDidFinishLoading调用时,[NSApp stopModal]不起作用,需要调用[NSApp abortModal]。

答案 1 :(得分:3)

首先,你开始连接太复杂了。改为:

connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]

删除[connection start]。现在:

  • 你的应用程序肯定正常运行运行循环吗? NSURLConnection要求它起作用。
  • 您是否能够执行URL请求的同步加载?
  • 在调试器中,您能看到url是您期望的吗?它是什么?
  • 您是否有可能在收到任何委托邮件之前取消分配WSHelper?毕竟NSURLConnection是异步的。

使用NSURLConnection并不需要做任何特别的事情,它是Foundation框架的一个简单部分。无需特殊的编译器设置。使用前无需初始化。没有。请不要盲目尝试引入CoreServices.Framework等内容。

由于同步发送请求有效,因此处理异步方面时必定存在问题。它可能是:

  • runloop未在NSDefaultRunLoopMode中运行,因此连接无法自行安排。
  • 代码的其他部分在有机会加载之前在连接上调用-cancel
  • 您正在设法在有可能加载之前解除分配连接。

真正的问题

啊,事实上我刚刚意识到发生了什么。你在打电话:

-[NSApp runModalForWindow:]

阅读此方法的说明。它没有像NSURLConnection期望的那样运行运行循环。我会说,实际上,你不想在为它运行URL连接时提供一个像这样的窗口。

我还建议你实现-connection:didReceiveResponse:委托方法。您想在此处检查服务器是否返回了预期的状态代码。

答案 2 :(得分:3)

你说你在模态对话框中使用它吗?模态对话框将运行循环置于不同的模式。除了正常的运行循环模式之外,您应该能够通过安排它在模式对话框运行循环模式下运行来使其工作。在connection

中分配loadURL:后,请尝试添加此行代码
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSModalPanelRunLoopMode];

希望有所帮助。

答案 3 :(得分:1)

你怎么知道它没有做任何事情?编译期间是否有任何错误或警告消息?程序运行时是否在控制台上显示任何错误消息?

您是否尝试在代码中设置断点并跟踪您期望发生的事情?