Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 执行多线程的正确方法_Iphone_Objective C_Ios_Multithreading_Ios5 - Fatal编程技术网

Iphone 执行多线程的正确方法

Iphone 执行多线程的正确方法,iphone,objective-c,ios,multithreading,ios5,Iphone,Objective C,Ios,Multithreading,Ios5,我是iPhone开发新手,在过去的几个月里,随着时间的推移,我一直在断断续续地开发一款应用程序。特别是,我编写了一个更新函数,用在线mysql数据库中的数据更新手机上的sqlite数据库。更新本身工作正常,但在更新完成之前,它冻结了UI 这真的没什么大不了的,但即使手机应用程序说它正在更新(按钮保持按下时的蓝色,上面的文字变为“更新”,上面还有一条短信说它正在更新),一些人仍然不知道它正在更新。。。所以,我想把更新放进它自己的线程中,这样我就可以在屏幕中间显示小的处理图像(因为当我没有多线程的时

我是iPhone开发新手,在过去的几个月里,随着时间的推移,我一直在断断续续地开发一款应用程序。特别是,我编写了一个更新函数,用在线mysql数据库中的数据更新手机上的sqlite数据库。更新本身工作正常,但在更新完成之前,它冻结了UI

这真的没什么大不了的,但即使手机应用程序说它正在更新(按钮保持按下时的蓝色,上面的文字变为“更新”,上面还有一条短信说它正在更新),一些人仍然不知道它正在更新。。。所以,我想把更新放进它自己的线程中,这样我就可以在屏幕中间显示小的处理图像(因为当我没有多线程的时候,图像也冻结了)。 我的问题是:我不知道在“暂停”应用程序(不允许用户导航到其他页面等)时启动线程的正确方式,然后在完成后“取消暂停”应用程序

事实上,我有这个工作,但只有在模拟器。在我们上传到iTunes并在他们批准后下载后,它就不起作用了。应用程序将永远暂停。这是我目前的代码:

启动更新过程的主线程:

- (IBAction)update:(id)sender{
    [NSThread detachNewThreadSelector:@selector(doUpdate:) toTarget:[UpdateViewController class] withObject:nil];

    canGo = FALSE;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadDone:) name:NSThreadWillExitNotification object:nil];

    while (!canGo){
    }

    [activity stopAnimating];
    activity.hidden = YES;
    status_text.text = @"Update Successful!  You may have to close and restart the app.";
}
正如您在这里看到的,我创建了另一个线程,然后有一个while循环无限期地阻止所有其他进程的发生,这样用户就无法在程序中导航。(我知道这肯定是错误的,但我找不到正确方法的示例。)在调用此函数之前,我启动处理图像的动画。(是的,我知道从我所读的内容来看,这些在技术上并不是“函数”,但请原谅使用了错误的术语。正如我所说,我是新来的。)

然后,在新线程中:

+ (void)doUpdate:(id)param{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

    // Stuff happens here

    UpdateViewController *talkThread = [[UpdateViewController alloc] init];
    [talkThread threadDone:nil];

    [pool drain];
}
和另一个由两者调用的函数(在模拟器上工作,但在iTunes下载后不工作):

我还尝试注释了调用“threadDone”函数的代码,在我的新线程中,我使用了:

[self performSelectorOnMainThread:@selector(finishLoop) withObject:nil waitUntilDone:FALSE];
使用与threadDone完全相同的新函数:

-(void)finishLoop{
    NSLog(@"Finish Loop");
    canGo = TRUE;
}
这根本没用。在调试器中,当我逐步完成更新时,根本没有调用finishLoop。但是我在“performSelectorOnMainThread”行中没有错误,所以我不明白这有什么问题


因此,我非常感谢有人解释设置另一个线程的正确方法,该线程将暂停UI而不冻结它(这样我可以在更新时显示“hotels have updated”之类的文本,这样进度图像就不会冻结),然后在更新完成后取消暂停UI。非常感谢您,因为这已经很痛苦了。

为了防止用户在后台工作时去任何地方,您应该在每个UIControl上设置启用属性(UIButton、UIExtField等),或者在整个UI上覆盖一个透明的UIView以阻止触摸事件。无限循环永远不是正确的答案。使用它们的效果将破坏使用背景线程的目的。如果您不确定在更新过程中如何阻止特定的用户操作,请在评论中发布,我们可以找到答案。

您可以使用并节省一些工作。 这东西正好适合你的需要。在后台执行某些工作时显示流程指示器。

您看过框架了吗?它是开源的,似乎满足了您的需求


是一个iPhone插件类,在后台线程中完成工作时,显示一个半透明的HUD,带有进度指示器和一些可选标签。HUD旨在取代未记录的专用UIKit UIProgressHUD,并具有一些附加功能。

若要防止用户与UI交互,请调用
[[UIApplication sharedApplication]beginIgnoringInteractionEvents]
。当允许用户再次交互时,调用
endigning…

编辑:您询问了线程结束时如何调用某个对象。这就是GCD线程体系结构的外观:

dispatch_async(my_queue, ^{
    // ... do stuff in a background thread ...
    dispatch_async(dispatch_get_main_queue(), ^{
        // ... the thread is over, do stuff on the main thread ...
    });
});

其实很简单。

我不希望用户能够做任何事情。UI冻结实际上对我来说还不错。但是现在我需要把动画图像放上去显示更新正在进行,我不能再让UI冻结了。这听起来不错,但我不知道如何在线程完成时正确调用某些东西。它似乎可以在模拟器上工作,但从iTunes下载后就不行了。好吧,第一步是不要使用所有的
detachNewThreadSelector:
东西。这样的情况正是我们有幸获得中央大调度的原因。这使得在线程结束时很容易在主线程上调用某些内容。我不确定如何设置“myqueue”变量,但我将其设置为
dispatch\u queue\u t my\u queue=dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u DEFAULT,0)。我在进入第一个队列时没有收到任何错误,但是
dispatch\u async(dispatch\u get\u main\u queue()^{
永远不会进入。它不会在这两者之间执行代码。事实上,我真的不需要第二个。因为这样可以保留所有内部变量的作用域,所以我可以翻转第一个队列底部的bool变量。这似乎行得通,我会在iTunes上发布它,看看它是否继续工作,然后让您知道。t又是汉克斯。如果我回答了你的问题,请接受我的回答。:)-我很担心你说话的方式,好像唯一的选择是在模拟器上测试还是在iTunes上发布。为什么不先在自己的设备上测试呢?但是否真的需要包含一个完整的类来翻转代码中的标志?我不需要任何额外的通知,只想知道线程何时退出。
dispatch_async(my_queue, ^{
    // ... do stuff in a background thread ...
    dispatch_async(dispatch_get_main_queue(), ^{
        // ... the thread is over, do stuff on the main thread ...
    });
});