1

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

附加说明:我还希望原始线程以这样的方式暂停,以便我仍然可以在我的界面中使用我的 2 个 UIButton。

关于我收到的问题的更多附加说明:这是我正在制作的游戏。在我的一种方法中,中间代码的某个地方意味着在我的主线程中。这种方法决定了我向哪个方向移动,然后我得到一个标签差异,然后进行攻击。但有时可以进行 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;

    }
}

线程方法

-(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
}
4

2 回答 2

5

您请求的内容是不可能的,主线程是处理用户交互的线程,每当您“停止”主线程时,界面就会变得无响应。

根据苹果的文档:

应用程序的主运行循环负责处理所有与用户相关的事件。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; 这将禁用屏幕上的所有交互,直到您将其设置回“YES”。

编辑2:

您更改流程的方式因您用于制作游戏的 OpenGL 而异?石英2D?简单的观点?

感觉你有点迷茫,你可能想从这里开始:

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

于 2013-12-05T00:57:49.123 回答
-1

看起来你做错了。按照设计,不应阻塞主线程。您应该使用从后台线程到主线程的某种回调/委托来设置标签决策。我会提供更多信息/示例,但我不确定您想要实现什么或您的“中间代码”部分发生在哪里。我以为是主线程,但后来你调用一个选择器在主线程上执行。

于 2013-12-04T23:55:49.450 回答