2011-02-04 11 views
0

私はメインスレッドを持つGUIアプリケーションを持っています。そして、ユーザーがスタートボタンをクリックすると、NSOperationを使って2つのスレッドを実行します。今度はあるスレッドがある値を計算して更新します。スレッド2がやりたいことは、この値を選択してUIを更新することです。 この2番目のスレッドからUIで更新されるIBOutlet Textfield値を取得するにはどうすればよいですか?別の.mファイルからCocoaのUIを更新する

例: main.m --- UIを処理し、ユーザーが開始ボタンを押すと2つのスレッドを開始するコードがあります。

thread1.m - 特定の値を計算し、ユーザーが停止するまでそれを続けます。

thread2.m - このスレッドを使用して、main1.mのUIをthread1.mが計算する値で更新する必要があります。

私はthread2.mタスクを達成できず、UIを更新できません。私の問題は、main.mがこの値にアクセスしてUIを更新するように、IBOutletを定義してthread2/1の値で更新する方法です。私はmain.mの実際の変数にアクセスし、NSLogを使ってそれを印刷することができます。そのちょうど私はこの値でUIを更新する方法に固執しています。私はmain.m内にIBOutletを持っていなければならないので、アプリ内のUILabelと結びつける必要があります。どんなアイディアですか?ありがとう。

答えて

0

thread1.mとthread2.mファイルへのポインタを追加できますか?次に、それらをコンストラクタメソッドまたはアクセサメソッドのいずれかで設定しますか?

私はあなたの例で説明した状況を理解し、あなたが計算しているものと仮定して(あなたが必要としてあなたが変更することができます)intの場合:

-(int)showCurrentCalcValue 
{ 
    //Assume that you get calculatedValue from whereever else in your thread. 
    return calculatedValue; 
} 
をthread1.mするアクセサを追加します。

は、その後、あなたmain.mは、以下のようなものであると仮定

NSTextField *guiTextField; 
Thread1 *thread1; 

-(void) setThread: (Thread1 *aThread) 
{ 
    self.thread1 = aThread; 
} 

-(void) setGuiTextField: (NSTextField *aTextField) 
{ 
    self.guiTextField = aTextField; 
} 

-(void) updateGUI() 
{ 
    [guiTextField setStringValue: [thread1 showCurrentCalcValue]]; 
} 

をthread2.mに追加します

IBOutlet NSTextField *outputDisplay 

-(void) setUpThreads() 
{ 
    Thread1 *thread1 = [[Thread1 alloc] init]; 
    Thread2 *thread2 = [[Thread2 alloc] init]; 

    [thread2 setGuiTextField: outputDisplay]; 
    [thread2 setThread: thread1]; 
    //Whatever else you need to do 
} 

次に、スレッドのすべてを設定してメソッドを呼び出すだけです。

+0

ありがとうございました。私のmain.mのguiTextFieldにどうすればアクセスできますか?私はthread1.mで(まさにあなたが言及したような)価値を得ることができます。しかし、私が実行している問題は、main.mでアクセスできるNSTextfieldにこの値を格納する方法です。私がthread2.mで宣言すれば、main.mはそれを見ません。 – ZionKing

+0

main.mにNSTextField *であるIBOutletがあるとしますか?そうであれば、スレッドに渡すことができます。上記のコードを更新して試してみました。 – Ryan

0

ソースコードファイルは関係ありません。 1つのファイルにすべてのものを入れることができます(これは良い考えではありません)。問題は変わりません。重要なことはクラスです。

クラスは単なるコードバッグではありません。それらをデザインし、名前を付け、各クラスの責任範囲を定義します。あるクラスやインスタンスがある種のことをします。あなたはそれらのものが何であるかを定義します。

NSOperationサブクラスを書くときは、スレッドについて心配しないでください。別のスレッドで実行されるという保証はありません。各操作は単なる作業単位です。あなたは何かをするための操作を書いています。

例:main.mは--- UIを処理し、2つのスレッドを開始するためのコードがある -

操作

- ユーザーが[スタート]ボタンをヒット。

thread1.m - 特定の値を計算し、ユーザーが停止するまでそれを続けます。

これは一つのことではありません。それは不確定な一連のものです。

thread2.m - このスレッドを使用して、main.mのUIをthread1.mが計算する値で更新する必要があります。

セカンダリスレッドからUIに触れてはいけません。 Threading Programming Guide、特にスレッドセーフティサマリを参照してください。

なぜこれもスレッド化されるべきではありません。メインスレッド上で動作するNSTimerを使うと、これをもっと簡単に行うことができます。

メインスレッドで「特定の値を計算する」が不適切な場合は、その操作を行うことができます。タイマーメッセージへのあなたの応答は操作を作成し、計算キューに追加します。ユーザーがstopを押すと、そのアクションはメインスレッドで処理されます。タイマーを無効にして、キューが残りの操作のすべてを終了するのを待ちます。

どちらの解決方法でも、「thread2.m」は完全に消え去ります。 UIへのあなたのアップデートは、メインスレッド上で完全に起こります。後者のソリューションでは、完了するまで待つ必要はありません。タイマーメッセージを受信するたびに、現在の進捗情報でUIを更新できます。

関連する問題