【问题标题】:Why NSURLConnection blocks my UI?为什么 NSURLConnection 会阻止我的 UI?
【发布时间】:2011-03-27 16:59:59
【问题描述】:

我一直在阅读有关此问题的几个主题和问题,但我没有找到解决方案。

我执行了一些异步调用

[NSURLConnection connectionWithRequest:anURLRequest delegate:self];

问题是我希望接口可以运行,但在连接完成之前它会被阻塞。

这是否解决了启动另一个线程?问题到底出在哪里?

编辑

好的,在检索数据后,我使用 NSXMLParser 解析它,它会同步执行并阻塞主线程。它是否正确?然后,也许我需要在另一个线程中解析。谁有导游?

【问题讨论】:

  • 你用什么方法执行那个调用?
  • 我在根视图控制器的子视图(不是表)上调用它。
  • 您可能应该从您正在做的事情中包含更多代码。如果不知道连接的初始化时间和方式,就很难排除故障。

标签: iphone nsurlconnection nsxmlparser


【解决方案1】:

来自文档:

发送给委托的消息将在调用此方法的线程上发送。为使连接正常工作,调用线程的运行循环必须在默认运行循环模式下运行。

您确定这段代码是在默认模式下的运行循环上调用的,而不是从您使用不同类型的运行循环模式创建的线程中调用的吗?

【讨论】:

  • 我不会在我的应用程序的任何部分创建任何线程。但我不知道系统是否自己创建了另一个线程,我错过了这件事。这可能吗?
【解决方案2】:

当您使用connectionWithRequest 时,UI 不应锁定。尝试在您的 UI 中创建一个标签,并让您的连接使用当前的数据量对其进行更新,如下所示:

- (void)downloadContentFromUrl:(NSURL *)url {   
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (connection) {
        receivedData = [[NSMutableData data] retain];
        self.downloadProgressLabel.text = @"Downloading...";
    } else {
        // oh noes!
    }
}

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [receivedData setLength:0]; 
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {   
    [receivedData appendData:data]; 
    int kb = [receivedData length] / 1024;
    self.downloadProgressLabel.text = [NSString stringWithFormat:@"Downloaded\n%d kB", kb];
}

connectionWithRequest 确实在它自己的线程中运行 - 您无需担心这一点。实际上它必须从主线程开始。查看NSUrlConnection 文档了解更多信息。

【讨论】:

  • 不仅锁定 UI,它还会延迟事件链直到下载完成。我触摸的所有响应者都会在下载后响应。
  • 我用标签尝试你的测试,直到下载结束才会更新:(
【解决方案3】:
+ (id)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate];

这个方法应该创建一个异步请求(这意味着它在后台运行并且不会阻塞 UI)。您应该检查文件中是否有另一个类/方法阻止了 UI(例如 NSData 的 '+ (NSData *)dataWithContentsOfURL:(NSURL *)URL')。

【讨论】:

  • 在我的项目中出现了 0 次“dataWithContentsOfURL”。虽然,你知道哪些是阻塞 UI 的选择器吗?也许我的代码中有其中之一。
  • 嗯,加载数据后UI是否仍然被阻塞(已调用didFinishLoading-method)?
【解决方案4】:

我不知道它是否可以帮助任何人,但我有同样的问题(异步 URL 请求阻塞 UI)但这是由于:

NSLog(@"dataReceived: %@", data);

在 connectionDidReceiveData 方法中。

【讨论】:

    【解决方案5】:

    在我的例子中,我试图更新 UIProgressView.progress 属性。我是这样计算新值的

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        [self.progress setProgress:self.downloadedData.length / self.fileSize ];
        [self.downloadedData appendData:data];
    }
    

    这不起作用,我用

    替换了这段 sn-p 代码
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        self.downloadedSize += data.length;
        [self.progress setProgress:self.downloadedSize / self.fileSize ];
        [self.downloadedData appendData:data];
    }
    

    现在进度视图更新没有问题。

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      相关资源
      最近更新 更多