gpt4 book ai didi

objective-c - Objective-C 中的异步调用

转载 作者:太空狗 更新时间:2023-10-30 03:27:06 24 4
gpt4 key购买 nike

我正在尝试从网站获取数据 - xml。一切正常。

但在返回 xml 数据之前,UIButton 一直处于按下状态,因此如果互联网服务出现问题,则无法更正,应用程序实际上无法使用。

调用如下:

{
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];
}

它工作正常,但我怎样才能让 View 按钮在卡住的情况下发挥作用。换句话说,我只希望 UIButton 和其他 UIButton 能够在后台运行时发挥作用。

我听说过 performSelectorInMainThread,但我无法正确实践它。

最佳答案

您不太了解线程模型,如果您在没有真正了解发生了什么的情况下开始添加异步代码,您可能会搬起石头砸自己的脚。

您编写的代码在主应用程序线程中运行。但是当你想到它时,你不必编写任何 main 函数——你只需实现应用程序委托(delegate)和事件回调(例如触摸处理程序),并且它们会以某种方式在时机成熟时自动运行.这不是魔术,这只是一个名为 Run Loop 的 Cocoa 对象.

Run Loop 是一个接收所有事件、处理计时器(如在 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

现在 yourCode 执行您想要执行的操作,Run Loop 继续运行。但是当您的代码需要很长时间才能完成时,例如您的情况,运行循环必须等待,因此在您的代码完成之前不会处理事件。这就是您在应用程序中看到的内容。

要解决这种情况,您必须在另一个线程中运行长操作。这不是很难,但是您仍然必须考虑一些潜在的问题。在另一个线程中运行就像调用 performSelectorInBackground 一样简单:

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

现在您必须想办法告诉应用程序数据已经加载,例如使用通知或在主线程上调用选择器。顺便说一下:将数据存储在应用程序委托(delegate)中(或者甚至使用应用程序委托(delegate)来加载数据)并不是非常优雅的解决方案,但那是另一回事了。

如果您确实选择了 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];
});
});

关于objective-c - Objective-C 中的异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2708776/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com