在我的应用程序中,根视图控制器从Internet获取信息,对其进行解析,并在viewDidAppear
中显示。我正在使用这种方法,因为我的应用程序嵌入在UINavigationController
中,这样当用户按下后退按钮并弹出到根视图时,根视图控制器将重新加载其数据。
发生这种情况时,需要一些时间来获取和显示来自互联网的信息。在此期间,如果用户单击按钮移动到其他视图,则在视图控制器完成其获取Web数据的过程之前,不会执行按钮操作。
如何才能使按钮覆盖其他进程并立即切换视图?这样安全吗?提前谢谢。
修改
以下是我从网站上获取信息的部分示例(我的应用程序解析HTML)。
NSURL *siteURL = [NSURL URLWithString:@"http://www.ridgefield.org/ajax/dist/emergency-announcements"];
NSError *error;
NSString *source = [NSString stringWithContentsOfURL:siteURL
encoding:NSUTF8StringEncoding
error:&error];
答案 0 :(得分:2)
这是苹果公司会追捕的地方,“不要阻止主线!”。
此类工作流的主要建议是使用单独的线程(读取:队列)从Web加载数据。然后,完成加载的worker可以在视图控制器上设置一些属性,并在该setter内部应该更新UI。记得在主线程上重新调用setter。
有几种方法可以对并发猫进行换肤,但是这个特定问题的答案会使它们超出范围。简短的回答是不要在主线程中执行加载,这应该会引导您到达正确的位置。
答案 1 :(得分:1)
NSString方法stringWithContentsOfURL是同步的,会阻塞你的主线程。
您可以使用异步URL请求,而不是使用后台线程来解决问题。这不会阻止用户界面,因为委托协议用于通知您何时完成请求。例如:
NSURL *url = [NSURL URLWithString:@""http://www.ridgefield.org/ajax/dist/emergency-announcements""];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLConnection* theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
然后你的一些委托方法是:
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)theResponse
{
// create received data array
_receivedData = [[NSMutableData alloc] init];
}
-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)theData
{
// append to received data.
[_receivedData appendData:theData];
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
// now the connection is complete
NSString* strResult = [[NSString alloc] initWithData: _receivedData encoding:NSUTF8StringEncoding];
// now parse strResult
}