0

我有一个应用程序,我正在访问一个远程网站NSURLConnection来运行一些代码,然后保存一些 XML 文件。然后我将访问这些 XML 文件并通过它们进行解析以获取信息。该过程运行良好,只是我的用户界面没有正确更新。我想通过我的UILabel. 我正在尝试使用setBottomBarToUpdating:. 当我将其设置为“处理中请稍候...”时,它第一次起作用;但是,connectionDidFinishLoading:它不会更新。我在想我的 NSURLConnection 正在一个单独的线程上运行,而我dispatch_get_main_queue在主线程上更新的尝试不起作用。我怎样才能改变我的代码来解决这个问题?谢谢![如果我需要包含更多信息/代码,请告诉我!]

我的文件.m

NSLog(@"Refreshing...");

dispatch_sync( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     [self getResponse:@"http://mylocation/path/to/file.aspx"];
});

[self setBottomBarToUpdating:@"Processing Please Wait..."];

queue = dispatch_queue_create("updateQueue", DISPATCH_QUEUE_CONCURRENT);

连接完成加载:

if ([response rangeOfString:@"Complete"].location == NSNotFound]) {
  // failed
} else {
  //success
  dispatch_async(dispatch_get_main_queue(),^ {
       [self setBottomBarToUpdating:@"Updating Contacts..."];
  });

  [self updateFromXMLFile:@"http://thislocation.com/path/to/file.xml"];

  dispatch_async(dispatch_get_main_queue(),^ {
       [self setBottomBarToUpdating:@"Updating Emails..."];
  });

  [self updateFromXMLFile:@"http://thislocation.com/path/to/file2.xml"];  

}
4

3 回答 3

1

在我的 connectionDidFinishLoading: 我会尝试这样的事情:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {
    if ([response rangeOfString:@"Complete"].location == NSNotFound]) {
      // failed
    } else {
      //success
      dispatch_async(dispatch_get_main_queue(),^ {
           [self setBottomBarToUpdating:@"Updating Contacts..."];
      });

      [self updateFromXMLFile:@"http://thislocation.com/path/to/file.xml"];

      dispatch_async(dispatch_get_main_queue(),^ {
           [self setBottomBarToUpdating:@"Updating Emails..."];
      });

      [self updateFromXMLFile:@"http://thislocation.com/path/to/file2.xml"];  
    }
});

然后所有文件访问都发生在后台队列中,因此主队列没有被锁定。主队列也将更快地完成对 connectionDidFinishLoading 的调用,因为您将所有艰苦的工作投入到默认队列中,这应该让它(和主线程)准备好接受您对 UI 更新的排队这将由默认队列在处理您刚刚加入它的块时完成。

队列切换变为

  • connectionDidFinishLoad 的主线程回调:
  • 快速切换到默认全局队列释放主线程
  • 最终移交给 setBottomBarToUpdating 的主队列:调用
  • 在主线程上执行主队列块以正确更新 UI
  • 最终完成主队列上的块
  • 最终完成默认队列上的块

您增加了并发性(在您拥有良好的多核设备的情况下很好),并且您已经从主线程中减轻了 I/O 的负担(对它来说从来都不是一个好地方),而是专注于用户界面工作(合适的地方)。

理想情况下,您也可以在主线程之外运行 NSURLConnection 运行循环,但这可能足以让您继续前进。

于 2012-11-10T15:31:31.640 回答
0

您在哪个运行循环中运行 NSURLConnection?如果它是主循环,则您正在排队 setBottomBarToUpdating: 调用您已经在做的工作,因此可能是您没有看到 UI 更新的原因。

于 2012-11-08T16:57:58.237 回答
0

你也可以performSelectorOnMainThread这样尝试:

if ([response rangeOfString:@"Complete"].location == NSNotFound]) {
                // failed
            } else {
                //success
                [self performSelectorOnMainThread:@selector(setBottomBarToUpdating) withObject:@"Updating Contacts..." waitUntilDone:false];

                [self updateFromXMLFile:@"http://thislocation.com/path/to/file.xml"];

                [self performSelectorOnMainThread:@selector(setBottomBarToUpdating) withObject:@"Updating Emails..." waitUntilDone:false];


                [self updateFromXMLFile:@"http://thislocation.com/path/to/file2.xml"];  

            }
于 2012-11-08T16:53:06.247 回答