微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

异步调用Objective C iphone

我正在尝试从一个网站xml获取数据.一切都很好.

但是UIButton仍然按下,直到xml数据被返回,因此如果这是一个互联网服务的问题,它不能被纠正,应用程序实际上是不可用的.

这里是电话:

{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if(!appDelegate.XMLdataArray.count > 0){
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        [appDelegate GetApps]; //function that retrieves data from Website and puts into the array - XMLdataArray.

    }
    XMLViewController *controller = [[XMLViewController alloc] initWithNibName:@"MedGearsApps" bundle:nil];
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];
}

它工作正常,但如何使视图按钮功能与卡住.换句话说,我只是想让UIButton和其他UIButton在后台运行起来.

我听说过PerformSelectorInMainThread,但我不能把它正确地练习

任何帮助是赞赏:)

解决方法

你不太了解线程模型,如果您开始添加异步代码,而不必了解发生了什么,您可能会自己拍摄自己的脚步.

您编写的代码在主应用程序线程中运行.但是,当你想到它时,你不必写主要的功能 – 你只需要实现应用程序委托和事件回调(如触摸处理程序),并且以某种方式在时间到来时自动运行.这不是一个魔术,这只是一个名为Run Loop的Cocoa对象.

运行循环是接收所有事件的对象,处理定时器(如NSTimer中)并运行代码.这意味着,例如,当您在用户点按按钮时执行某些操作,调用树看起来有点像这样:

main thread running
    main run loop
        // fire timers
        // receive events — aha,here we have an event,let’s call the handler
        view::touchesBegan…
            // use tapped some button,let’s fire the callback
            someButton::touchUpInside
                yourCode

现在,您的代码执行您想要执行的操作,“运行循环”继续运行.但是,当您的代码完成时间太长,例如在您的情况下,运行循环必须等待,因此在代码完成之前,事件将不会被处理.这是你在应用程序中看到的.

解决这种情况,你必须在另一个线程中运行长操作.这不是很难,但是你必须考虑几个潜在的问题.在另一个线程中运行可以像调用performSelectorInBackground一样简单:

[appDelegate performSelectorInBackground:@selector(GetApps) withObject:nil];

而现在你必须考虑一种告诉应用程序已经加载数据的方法,例如在主线程上使用通知调用选择器.顺便说一下:将数据存储在应用程序委托中(甚至使用应用程序委托来加载数据)不是很优雅的解决方案,但这是另一个故事.

如果您选择performSelectorInBackground解决方案,请查看有关memory management in secondary threads的相关问题.您将需要自己的自动释放池,以便您不会泄露自动释放的对象.

在一段时间后更新答案 – 现在通常最好使用Grand Central dispatch在后台运行代码

dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
    // No explicit autorelease pool needed here.
    // The code runs in background,not strangling
    // the main run loop.
    [self doSomeLongOperation];
    dispatch_sync(dispatch_get_main_queue(),^{
        // This will be called on the main thread,so that
        // you can update the UI,for example.
        [self longOperationDone];
    });
});

原文地址:https://www.jb51.cc/c/114648.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐