【问题标题】:What's wrong on following URLConnection?关注 URLConnection 有什么问题?
【发布时间】:2010-10-16 22:06:58
【问题描述】:

另见:

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 开发的不同线程上运行 NSURLConnection 的解决方案在文档中的任何地方都没有示例代码,这使得所有内容都难以编码。

【问题讨论】:

  • sendSynchronousRequest:returningResponse:error: 不起作用,因为它是一个类方法,并且异常表明您已将其发送到实例。
  • 谢谢,我会尝试修复它,但无论如何我正在寻找异步解决方案,我很累......
  • 我了解您正在寻找异步解决方案,但正如文档所说,同步方法在内部使用异步代码。它的结果将告诉我们更多关于你的代码失败的地方。

标签: objective-c cocoa asynchronous nsurlconnection


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    首先,您使启动连接过于复杂。改为:

    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: 委托方法。您想在此处检查服务器是否正在返回预期的状态代码。

    【讨论】:

    • 不,我没有释放任何东西。对于同步请求,我收到此错误.. [NSURLConnection sendSynchronousRequest:returningResponse:error:]: unrecognized selector sent to instance。我对任何编译器设置或我必须添加到项目以使其工作的任何东西有疑问?
    • 另外,如果你在单独的线程上运行它,它不会工作,因为线程没有运行循环,除非你给它们一个。
    • [NSURLConnection sendSynchronousRequest:returningResponse:error:] 是一个类方法。我怀疑您正试图将其发送到 NSURLConnection 的实例。
    • 谢谢我现在尝试了同步方法,它确实有效,但我正在寻找异步解决方案。
    • 我发现 NSURLConnection 在模态对话框上不起作用的问题,我必须创建一个新线程并在其上调用 NSURLConnection,我想这是另一个问题..
    【解决方案3】:

    您说您在模态对话框中使用它?模态对话框将运行循环置于不同的模式。除了正常的运行循环模式之外,您应该能够通过安排它在模式对话框运行循环模式下运行来使其工作。尝试在loadURL:中分配connection后添加这行代码

    [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSModalPanelRunLoopMode];
    

    希望对您有所帮助。

    【讨论】:

    • 不,它没有用,我累了......我没有得到任何提供正确解决方案的样本,现在我在某处读到你必须运行模态会话,但最糟糕的是苹果在文档中的任何地方都没有关于如何让事情正常工作的示例代码!
    【解决方案4】:

    你怎么知道它什么也没做?编译过程中是否有任何错误或警告消息?程序运行时控制台是否显示任何错误消息?

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

    【讨论】:

    • 当然它可以编译,我们无法调试 NSURLConnection 因为没有一个委托被调用,我尝试放置断点并且没有调用委托,我看到 loadUrl 确实运行成功,在日志中也没有错误!!,我不知道它是否开始
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 2021-04-07
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多