2012-06-14 12 views
6

actionSheet:clickedButtonAtIndexデリゲートメソッドでUIActionSheetを作成しています。応答時間が長いUIActionSheet

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex  
if(buttonIndex == 1){ 

     [self.myFirstView removeFromSuperview]; 

     if (!self.mySecondView) { 
      [[NSBundle mainBundle] loadNibNamed:@"MySecondView" owner:self options:nil]; 
     } 
     [self.mySecondView setFrame:CGRectMake(0, 0, 320, 480)]; 

     [[UIApplication sharedApplication].keyWindow addSubview: self.mySecondView]; 

     UIActionSheet * action = [[UIActionSheet alloc]initWithTitle:@"" 
                  delegate:self 
                cancelButtonTitle: nil 
               destructiveButtonTitle: deleteContacts 
                otherButtonTitles: cancel, nil]; 
     action.tag = 102; 
     [action showInView:self.view]; 
     [action release]; 

    } 

私はこのUIActionSheetのクリックイベントを上記と全く同じ方法で処理します。

if(actionSheet.tag == 102){ 

    if(buttonIndex == 0){ 
     if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { 
      [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)]; 
      [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView]; 
     } 
     [self.mySecondView removeFromSuperview]; 

     [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; 

     [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; 

    } 
} 

私が直面しています問題は、UIActionSheetが応答する時間がかかりすぎるということです。 UIActionSheetボタンをクリックすると、フリーズ状態の2〜3秒前に、myThirdViewが読み込まれます。私はUIActionSheetボタンのクリックイベントメソッドで最初に行うように、この場合の応答の遅延はmyThirdViewをロードすることになっています。残りのコードは、myThirdViewをロードするコードの後に​​のみ実行されます。しかし、コードの最初の行でさえ遅れて実行されているようです。 提案がありますか?

+0

それは' [self.viewアクションshowInView]を動作しますか? – Felix

+0

それは動作します。しかし、アクションシートの応答速度に大きな変化はありません。 –

+0

私は正しい答えはザードとアンドリュージマーの答えを組み合わせるべきだと思います。バックグラウンドスレッドで実行されるべきコードは、次のコード行です。 '[self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton];'。 'RemoveView'メソッドを含む残りのコードは、メインスレッド上で実行されていなければなりません。ボタンタッチアクションをシミュレートするためのガブリエルに特別な言及。 –

答えて

2

質問。 UIActionSheetがフリーズするか、それとも消えて3番目のビューが2〜3秒間表示されないのですか?

これは2つの問題の1つに起因する可能性があります。

  1. 全体のアクションシートがフリーズした場合、あなたが第三ビューは、あなたには、いくつかのコアデータ、または資産の多くは、または長い時間がかかっているものをロードしていることをinitにするとき、あなたは、いくつかの重い物を持ち上げるを行っています。この場合、3番目のビューを読み込む方法を再フォーマットする必要があります。重い荷物をバックグラウンドにプッシュすることをお勧めします(これは、xibにたくさんの画像がある場合は、コードでロードする必要があるかもしれません)。

  2. もう1つの可能性は、2番目のビューの下に3番目のビューを追加してから、2番目のビューを3秒間隠すことではない(遅延でセレクタを実行することによって行われます)。このような場合は、遅延を削除するだけです。

実行時間を短縮し、コード内でボトルネックを見つけるのに役立ついくつかのクラスを作成しました。 http://forrst.com/posts/Code_Execution_Timer_for_iOS_Development-dSJ

3

これはおそらく、この

[self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; 

によるものであるが、他の方法を作り、その方法でこれを行います。この

[self viewRemover]; 

とviewRemover

-(void) viewRemover 
{ 
    [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; 

} 

のようなので、あなたのコードは次のようになり、今

if(actionSheet.tag == 102){ 

    if(buttonIndex == 0){ 
     if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { 
      [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)]; 
      [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView]; 
     } 
     [self.mySecondView removeFromSuperview]; 

     [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; 

    [self performSelectorInBackground:@selector(viewRemover) withObject:nil]; 

    } 
} 
+0

それを試してみてください。動いていない。 –

+0

更新を参照してくださいans – Saad

+0

私は行を変更しました – Saad

3

ユーザー・インタフェースの操作は、メインスレッドで実行し、あなただけの方法が終了したときに発生します。したがって、MyThirdViewは、他の指示が完了するまで表示されません。

[self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; 

あなたはそれが理由であることを確認するために、任意の重い計算やネットたっを行っている場合:私は理解することができる唯一のことは、つまり遅らせています。あなたはボタンのタッチアクションをシミュレートしたい場合は

[self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton]; 

OTOH、私はあなたがより良い、その行を変更したいと思います。

+0

大きな違いはありません。 –

1

あなたの3番目のビューはどれくらい大きいですか。 nibファイルをあまりにも多くロードする必要がある場合は、UI要素を変更してUIスレッドをブロックする必要がある場合や、タイムアウトが発生してアプリが移行するまで、

に..私はこれを取るルートを補償するためのいくつかのものは、UIスレッドではあまりやって

// This will release the UI thread which may be blocking your calls. 
// You can use any of the DISPATCH_QUEUE_PRIORITY_.... values to set how important this block is. 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    // this command will get added to the stack and return without a hitch. 
    // the block will be run the next time the main runloop ends. 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // do some UI work that can happen without a hitch, and does not impact the calling block 
    }); 

    // this command will act much the same. but will pause the background execution 
    // of this block until the runloop has executed this and returned. 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // do some UI work that must be completed to continue. 
    }); 

}); 

dispatch_asyncとdispatch_syncあるキューに積載され得るものの実行を一時停止します。 UIを変更する必要があるときは、すべてのコードをバックグラウンドスレッドに配送し、UIスレッドにスキップするだけで、iPhoneアプリをコーディングするための、より応答性の高い方法です。 [:self.mySecondViewアクションshowInView]; `` `へ;:あなたが変更されたときに

私はこれが役に立てば幸い:)

+0

このコードブロックは私の命を救ってくれました。 AUTORELEASEオブジェクトをITに受け渡さないように注意してください。それはブロックなので、時にはあなたができるように感じる。 –

+0

私は現在アークを使用しています。しかし、私は、ブロックが保持しているオブジェクトをすべて保持し、解放すると信じています。それはない? –

+0

ARCを使用しているときにそれができないのかどうかは分かりません。あなたがARCにいないのであれば、スレッド間でオートレリースされたオブジェクトを渡すことはむしろ悲惨です。私はこれで過去に燃えた。 –

関連する問題