2

特定の時点でアプリがフリーズするという奇妙な問題が発生しています。私はそれが私がどのように使用しているかに関係していると推測しています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];
}
4

1 に答える 1

0

私はBryanChenに同意します.別の問題があると思います. 調査ライブラリの詳細がなければ確認することはできませんが、一連の質問を進めるためにタッチ入力を受け入れるのが UIViewController であると仮定すると、なぜそれがスレッド化の問題であるかを理解するのは困難です - 単に進めるべきではないユーザーの介入なしで。

それはさておき、あなたの使用もNSCondtionLock正しく見えません。

本質的にNSConditionLockは、現在の「状態」を表す NSInteger を持っていますが、数値と考えてください。次に、実行できる基本的な操作が 2 つあります。

lockWhenCondition:x「条件」が「x」になり、ロックが使用可能になるまで、現在のスレッドをブロックします。その後、ロックを要求します。

unlockWithCondition:yロックを解放し、条件を「y」に設定します

タイムアウトを設定する方法 ( lockBeforeDate) や、ブロックせずにロックを要求する方法 ( tryLocktryLockWhenCondition) もあります。

2 つのスレッドを同期するための一般的なパターンは次のとおりです。

  1. ロックを条件 'x' に初期化する
  2. スレッド 1 lockWhenCondition:x- このスレッドは x であるため、ロックを要求できます
  3. スレッド 2 lockWhenCondition:y- ロックが x であるため、このスレッドはブロックされます
  4. スレッド 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これは、何が機能し、最後まで直接スキップするのはなぜですか?という質問に戻ります。

于 2014-04-29T07:41:35.787 に答える