Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/102.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
iOS应用程序冻结与NSConditionLock_Ios_Iphone_Objective C_Nsthread_Nslock - Fatal编程技术网

iOS应用程序冻结与NSConditionLock

iOS应用程序冻结与NSConditionLock,ios,iphone,objective-c,nsthread,nslock,Ios,Iphone,Objective C,Nsthread,Nslock,我的应用程序在某一点冻结,这是一个非常严重的问题。我猜这与我如何使用NSConditionLock有关 有一个库我已经得到使用,其中包括一系列的调查问题,但它的工作方式,它直接比赛到最后一个问题,而不接受答案,因此需要暂停线程和接受用户的输入 我以前从未使用过它,所以如果我执行错误,也许有人可以帮助我? 如果提供的代码不够,请告诉我 - (void)viewDidLoad { [super viewDidLoad]; //INITIALISE CONDITION LOCK WITH CO

我的应用程序在某一点冻结,这是一个非常严重的问题。我猜这与我如何使用
NSConditionLock
有关

有一个库我已经得到使用,其中包括一系列的调查问题,但它的工作方式,它直接比赛到最后一个问题,而不接受答案,因此需要暂停线程和接受用户的输入

我以前从未使用过它,所以如果我执行错误,也许有人可以帮助我? 如果提供的代码不够,请告诉我

- (void)viewDidLoad
{
    [super viewDidLoad];
//INITIALISE CONDITION LOCK WITH CONDITION 0
     condition=[[NSConditionLock alloc]initWithCondition: 0];
}


- (IBAction)startPressed:(UIButton*)sender {
if (sender.tag == 1) {
//START BACKGROUND THREAD
 surveyThread = [[NSThread alloc] initWithTarget:self selector:@selector(runProjecttest)      object:nil];
        [surveyThread start];
}
else
{
 //DO SOME STUFF AND THEN UNLOCK
 [condition unlockWithCondition:1];
}
}


- (void) runProjecttest:(AbstractTask *)rendertask
{
// DO STUFF AND SHOW UI ON MAIN THREAD, THEN LOCK
[self performSelectorOnMainThread:@selector(showUI:) withObject:task waitUntilDone:YES];
 [condition lockWhenCondition: 1];
}
编辑:简而言之,我想要这个java代码片段的Objc等价物

this.runOnUiThread(showUI);
    try 
    {
        //SLEEP         
        Thread.sleep(1000*60*60*24*365*10);
    } 
    catch (InterruptedException e) 
    {
                   //WAKE
        setResponse(at,showUI);
    }
根据Paul的请求编辑2:ShowUI方法

 [self removePreviousSubViews];

 switch ([task getType]) {
        case SingleChoiceType:
        {
            NSLog(@"SingleChoiceType");
            isMultipleChoice = NO;
            [self addSingleChoiceView:nil];
            break;
        }
        case TextType:
        {
            NSLog(@"TextType");
            self.txtTextType.keyboardType=UIKeyboardTypeDefault;
            [self addTextTypeView:nil];

            break;
        }
...more cases
}

-(void)addTextTypeView:(NSSet *)objects
{
    self.txtTextType.text = @"";
    CGRect frame = self.txtQuestionType.frame;
//    frame.size = [self.txtQuestionType sizeThatFits: CGSizeMake(self.txtQuestionType.frame.size.width, FLT_MAX)];
        frame.size.height = [self textViewHeightForAttributedText:self.txtQuestionType.text andWidth:self.txtQuestionType.frame.size.width andTextView:self.txtQuestionType];


    self.txtQuestionType.frame=frame;

    self.textTypeView.frame = CGRectMake((self.view.frame.size.width - self.textTypeView.frame.size.width)/2, ( self.txtQuestionType.frame.origin.y+self.txtQuestionType.frame.size.height), self.textTypeView.frame.size.width, self.textTypeView.frame.size.height);

    [self.view addSubview: self.textTypeView];
}

我同意BryanChen的观点,我想你可能还有另一个问题。如果没有关于调查库的详细信息,就无法确认,但是假设它是一个UIViewController,而不是接受触摸输入来处理一系列问题,就很难理解为什么它是一个线程问题——如果没有用户交互,它就不应该前进

除此之外,您对
nsconditionlock
的使用看起来也不正确

本质上,
NSConditionLock
有一个表示当前“条件”的NSInteger,但只要把它看作一个数字即可。然后,您可以执行两个基本操作-

lockWhenCondition:x将阻止当前线程,直到“condition”为“x”且锁可用。然后它将请求锁

unlockWithCondition:y
解除锁定并将条件设置为“y”

还有一些方法可以设置超时(
lockBeforeDate
)并尝试在不阻塞的情况下请求锁定(
tryLock
tryLock when condition

要同步两个线程,一般模式为

  • 将锁初始化为条件“x”
  • 线程1
    lockWhenCondition:x
    -此线程可以声明锁,因为它是x
  • 线程2
    lockWhenCondition:y
    -此线程将被阻止,因为锁是x
  • 线程1完成工作,
    unlockWithCondition:y
    -这将使线程2能够声明锁并解除对该线程的阻止
  • 您的代码看起来很奇怪,因为您正在if子句中启动一个线程,但在else子句中解锁。我原以为你会有这样的东西-

    -(IBAction)startPressed:(UIButton*)sender {
        if (sender.tag == 1) {
        //START BACKGROUND THREAD
         surveyThread = [[NSThread alloc] initWithTarget:self selector:@selector(runProjecttest)      object:nil];
            [surveyThread start];
            [condition:lockWithCondition:1];     //  This will block until survey thread completes
            [condition:unlockWithCondition:0];   //  Unlock and ready for next time
        }
    
    }
    
    - (void) runProjecttest:(AbstractTask *)rendertask
    {
    // DO STUFF AND SHOW UI ON MAIN THREAD, THEN LOCK
    [condition lockWhenCondition: 0];
    [self performSelectorOnMainThread:@selector(showUI:) withObject:task waitUntilDone:YES];
    [condition unlockWithCondition:1];
    }
    
    但是对我来说,这看起来像是死锁的配方,因为您正在主线程上执行showUI选择器,该线程被阻塞,等待调查线程完成


    这让我们回到问题上来,
    showUI
    做什么?为什么它直接跳到了结尾?

    为什么你试图使用
    NSConditionLock
    @BryanChen请看我编辑的问题。你可能想读一下,忘掉
    NSConditionLock
    @akash我也有同样的问题。。。。!但无法解决我明白了,底线是我需要暂停/恢复一个线程,没有办法,所有谷歌搜索似乎都指向NSConditionLock,但如果你有更好的想法,欢迎你提出建议。感谢你的洞察力。showUI根据开关大小写从主视图中添加和删除子视图。什么驱动开关语句?从库中获取的问题类型,如数字问题或日期类型等。确定。我想我现在明白了。您正在使用
    addSubview
    /
    removeSubview
    ?什么触发了对removeSubview的调用?也许您应该使用
    UINavigationController
    或modally显示适当的视图控制器?您能否更新问题以显示
    showUI
    方法?我不是在演示新的控制器,它只是在self.view中添加和删除子视图。