我有一个应用程序,其中有一个与我们的SQL数据库同步的例程。我遇到了一些看似无法访问的问题。
例程的工作原理如下:
1 - 按下UIButton
2 - 检查互联网连接,是否有连接......
3 - 启动一个新线程以显示“正在加载”动画gif
4 - 下一页已加载。
if([self connectedToInternet] == YES)
{
[NSThread detachNewThreadSelector:@selector(loadAnimation) toTarget:self withObject:nil];
ObViewControllerAdminMenu *monitorMenuViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"webObservations"];
monitorMenuViewController.modalTransitionStyle = IModalTransitionStyleCrossDissolve;
[self presentViewController:monitorMenuViewController animated:YES completion:nil];
}
然后,使用webObservations页面中的viewDidLoad方法,我开始连接到SQL数据库。
我的问题是如果在同步过程中删除了互联网连接会发生什么?在我看来,该应用程序“超时”,由于缺乏响应,它关闭了自己。
我认为我说iPad在5秒钟不活动后会这样做是对的 - 这是对的吗?如果是这样的话有什么方法呢?
如果有帮助,则会在下方显示同步代码片段:
- (void)viewDidLoad
{
NSString *strURLClass = [NSString stringWithFormat:@"%@%@", @"http://www.website.co.uk/uploads/getiobserveinfo.php?schoolname=",obsSchoolName];
NSArray *observationsArrayClass = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
NSEnumerator *enumForObsClass = [observationsArrayClass objectEnumerator];
observationListFromSQL = [[NSMutableArray alloc]init];
id className, dateOfObs, teacher, startTime;
while (className = [enumForObsClass nextObject])
{
[observationListFromSQL addObject:[NSDictionary dictionaryWithObjectsAndKeys:className, @"obsClassName", nil]];
}
从崩溃日志中 - 请注意它也会在启动时运行例程
日期/时间:2013-09-20 11:56:31.731 +0300 操作系统版本:iOS 6.1.3(10B329) 报告版本:104
异常类型:00000020 例外代码:0x000000008badf00d 突出显示的主题:0
特定应用信息: uk.co.website未能及时发布
经过的总CPU时间(秒):2.080(用户2.080,系统0.000),5%CPU 经过的应用程序CPU时间(秒):0.312,1%CPU
答案 0 :(得分:1)
您的错误是:应用程序特定信息:uk.co.website未能及时启动
请避免使用同步功能来检索网络资源,initWithContentsOfURL只会在从网络下载完整网址时返回。 此方法调用将阻止应用程序启动。
有下载资源的异步方法,如NSURLConnection或使用第三方库,如AFNetworking
答案 1 :(得分:1)
错误代码0x000000008badf00d
表示您的应用程序没有崩溃,而是被iOS杀死,因为您的应用程序用户界面冻结并且响应时间过长。我怀疑这条线是罪魁祸首,
NSArray *observationsArrayClass = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
这是在主线程上调用的同步方法,从而导致UI冻结,直到看门狗超时并且您的应用程序被终止。
<强>解决方案强>
进行异步WS调用,以便不阻止主线程。您可以使用GCD来实现此目的。
- (void)doAsyncCall
{
//you can use any string instead "com.mycompany.myqueue"
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.mycompany.myqueue", 0);
dispatch_async(backgroundQueue, ^{
//Make WS call here.
//Parse response and create datasource for your UI elements
dispatch_async(dispatch_get_main_queue(), ^{
// Pass the datasource to the UI and update.
});
});
}
希望有所帮助!