ios - 使用NSConditionLock卡住iOS应用

标签 ios iphone objective-c nsthread nslock

我在某个时刻冻结了应用程序,这是一个比较棘手的问题。我猜想这与我使用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);
    }

编辑2:应Paul的要求使用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而不是接受触摸输入以处理一系列问题,很难理解为什么它是线程问题-它根本不应该前进无需用户交互。

除此之外,您对NSCondtionLock的使用也不正确。

本质上,NSConditionLock具有代表当前“条件”的NSInteger,但只需考虑一个数字即可。然后,您可以执行两个基本操作-
lockWhenCondition:x将阻塞当前线程,直到'condition'为'x'并且锁可用为止。然后它将要求锁定。
unlockWithCondition:y释放锁定并将条件设置为“y”

还有一些方法可以设置超时(lockBeforeDate)并尝试声明锁而不会阻塞(tryLocktryLockWhenCondition)。

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

  • 初始化锁定为条件'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是做什么的,为什么它会直接跳到最后呢?

    关于ios - 使用NSConditionLock卡住iOS应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23355445/

    相关文章:

    ios - 呈现一个 alpha 为 0.5 的 Controller

    iphone - UITableView 在点击时并不总是触发委托(delegate)方法

    iphone - iTunes Connect 中的应用程序名称出现问题,尝试使用已删除应用程序中的相同名称

    iphone - 通过 NSDictionary 获取您不知道 'Key' 的对象? IOS

    ios - 有效地循环包含可选值的月份和日期的jsonarray

    iphone - 如何将视网膜图像添加到svn

    ios - Core Plot Swift BarPlot tickLocation 始终为零

    iphone - 创建 Tableview 的自定义背景的正确方法

    objective-c - 有没有一种简单的方法可以将 NSString 拆分为字符数组?

    ios - UISwitch改变对象解析 objective-c