1

我有一个应用程序,其中有一个与我们的 SQL 数据库同步的例程。我遇到了一些似乎很差的 wifi 访问的问题。

例程是这样工作的:

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

4

2 回答 2

1

您的错误是:应用程序特定信息:uk.co.website 未能及时启动

请避免使用同步功能检索网络资源,initWithContentsOfURL 仅在从网络下载完整 url 时才会返回。此方法调用将阻止应用程序启动。

有异步方法来下载资源,如 NSURLConnection 或使用第三方库,如 AFNetworking

于 2013-09-26T07:52:13.233 回答
1

错误代码0x000000008badf00d意味着您的应用程序没有崩溃,而是被 iOS 杀死,因为您的应用程序 UI 冻结并且响应时间过长。我怀疑这条线是罪魁祸首,

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.
        });    
    });
 }

希望有帮助!

于 2013-09-26T07:52:40.090 回答