暂停主线程,直到后台线程检索用户输入

时间:2013-12-02 16:23:59

标签: ios nsthread nscondition

在我的主要启动线程中,我需要暂停代码并启动一个新线程并等到我收到用户输入。然后我想丢弃新的线程并返回到主线程停止的位置。但最新发生的是调用新线程,但主线程继续使用代码。如何在不干扰用户使用界面按钮的情况下处理此问题?我认为可能在我的if(moveCount == 2)语句中需要另一个nscondition?或者我的主线程需要等待来自我的其他线程的信号,通知用户输入。

附加说明:我还希望原始帖子暂停,以便我仍然可以在界面中使用我的2个UIButtons。

有关收到的问题的更多补充说明:这是我正在制作的游戏。在代码中间代码在我的主要线程中意味着我的一个方法。这个方法决定我在哪个方向移动,然后我得到一个标签差异,然后进行攻击。但有时可以进行2次攻击,因此此时用户可以通过2个按钮点击屏幕来决定要进行哪次攻击。

我也很安静地告诉我,我现在不应该暂停主线程。如果是这样,替代方案是什么?感谢

NSCondition和NSThread

@property (strong, nonatomic) NSCondition *condition;
@property (strong, nonatomic) NSThread *aThread;

在我的viewDidLoad中创建以下内容。

// create the NSCondition instance
self.condition = [[NSCondition alloc]init];

// create the thread
self.aThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadLoop) object:nil];

代码中间某处..

if(moveCount == 2){

        [self.aThread start];
    }

   // I need to get captureDecision from user from 2 buttons before continue.. How do I pause this thread when aThread is started. Then when capture decision is received discard aThread and start here.

    NSLog(@"Capture Decision = %d", captureDecision);
    if(captureDecision == 1){

        tagDifference = newButton.tag - currentButton.tag;

    }else{

        tagDifference = currentButton.tag - newButton.tag;

    }
}

aThread Method

-(void)threadLoop{

    NSLog(@"Thread Loop Triggered");
    while([[NSThread currentThread] isCancelled] == NO)
    {
        [self.condition lock];
        while(captureDecision == 0)
        {
            [self.condition wait];
        }

        [self.condition unlock];
    }
    [NSThread exit]; //exit this thread when user input is received
}

2 个答案:

答案 0 :(得分:5)

您要求的是不可能的,主线程是处理用户交互的线程,每当您“停止”主线程时,接口就会无响应。

基于apple的文档:

  

您应用的主要运行循环负责处理所有   与用户相关的事件。 UIApplication对象设置主运行   在启动时循环并使用它来处理事件和处理更新   基于视图的界面。顾名思义,主要运行循环   在应用程序的主线程上执行。这种行为可以确保   与用户相关的事件按照它们的顺序连续处理   收到了。

这意味着如果你停止主线程,你将无法做到。 https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW14

(除非有一些奇怪的方法让后台线程处理我可能不知道的用户交互,但仍然很奇怪)

正如其他人在此告诉你的那样,你的方法远非最佳。您必须问自己的问题是,您希望代码的哪一部分等待特定事件发生,以及出于何种目的。

如果您向我们提供您想要实现的更详细的解释,那么我们可以为您提供更好的解决方案。

编辑:

它是什么类型的游戏?转弯?像计时器一样不断绘制的东西。基本上你必须使用功能,例如,如果它是一个纸牌游戏,你会铺设所有卡并等待用户输入,当用户点击按钮时你会运行“计算结果函数”并在其中进行适当的更改登上并等待下一个输入。

如果你想暂停线程我会认为是因为某些东西在不断运行,有一个特殊的计时器与名为CADisplayLink的屏幕同步

https://developer.apple.com/LIBRARY/IOS/documentation/QuartzCore/Reference/CADisplayLink_ClassRef/Reference/Reference.html

您甚至可以“暂停”此计时器以等待用户的输入。

顺便说一句,如果你不想让用户与界面交互,直到事件发生,你所要做的就是self.view.userInteractionEnabled = NO;这将禁用屏幕上的所有交互,直到您将其设置回“是”。

编辑2:

改变流量的方式因您制作游戏OpenGL的用途而异? Quartz2D?简单的看法?

有点觉得你有点迷失,你可能想从这里开始:

http://www.raywenderlich.com/tutorials (向下滚动到制作游戏部分)

答案 1 :(得分:-1)

看起来你错了。根据设计,不应阻止主线程。您应该使用从后台线程到主线程的某种回调/委托来设置标记决策。我会提供更多信息/示例,但我不确定您要实现的目标或“代码中间某处”部分的位置。我想主线程,但是你调用一个选择器在主线程上执行。