私はiPhone開発の初心者です。特に、私はオンラインのmysqlデータベースからのデータで電話機のsqliteデータベースを更新する更新機能を書いていました。アップデート自体はうまくいきましたが、アップデートが完了するまでUIはフリーズしました。正しい方法でマルチスレッドを実行します
これは実際にはあまりにも大したことではありませんが、電話アプリが更新中であっても(ボタンは青色のまま押されていて、その上のテキストは「更新中」に変更されました。その上にあるテキストメッセージが更新しているように見える)、一部の人々はまだそれが更新されていることを知らなかった...だから私はそれを自身のスレッドに入れて、 (マルチスレッド化せずに画像を入れても画像が凍ってしまうので)
私の問題は、アプリケーションを「一時停止」している間にスレッドを開始する(ユーザーが他のページなどに移動することを許可しない)適切な方法を知らず、完了時にアプリケーションを「一時停止」します。
私は実際にはこの機能を持っていますが、シミュレータでのみ使用できます。 iTunesにアップロードして承認した後にダウンロードした後は、動作しません。アプリケーションは永久に一時停止されます。 、
- (IBAction)update:(id)sender{
[NSThread detachNewThreadSelector:@selector(doUpdate:) toTarget:[UpdateViewController class] withObject:nil];
canGo = FALSE;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadDone:) name:NSThreadWillExitNotification object:nil];
while (!canGo){
}
[activity stopAnimating];
activity.hidden = YES;
status_text.text = @"Update Successful! You may have to close and restart the app.";
}
あなたがここに見ることができるように、私は別のスレッドを作成し、その後whileループは無限に行われてから、他のすべてのプロセスを保持している:更新プロセスを開始し
メインスレッド、:ここに私の現在のコードですユーザーはプログラム内をナビゲートできません。 (私は間違っているはずですが、これを行う正しい方法の例は見つけられません)。この関数が呼び出される前は、処理イメージのアニメーションが開始されます。 (そして、はい、私はこれらが技術的に「機能」ではないことを知っていますが、間違った用語を言い訳してください)。 :
+ (void)doUpdate:(id)param{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
// Stuff happens here
UpdateViewController *talkThread = [[UpdateViewController alloc] init];
[talkThread threadDone:nil];
[pool drain];
}
、別の関数が両方によって呼び出される(シミュレータ上で動作しますが、これではないの後にiTunesのダウンロード):私も「threadDone」を呼び出すコードをコメントアウトしようとした
-(void)threadDone:(NSNotification*)arg {
NSLog(@"Exiting");
canGo = TRUE;
}
私の新しいスレッドでは、私は使用しました:
threadDoneとまったく同じことをした、新たな機能を持つ[self performSelectorOnMainThread:@selector(finishLoop) withObject:nil waitUntilDone:FALSE];
:
-(void)finishLoop{
NSLog(@"Finish Loop");
canGo = TRUE;
}
これはまったく何もしませんでした。デバッガでは、私がアップデートを進めていったときにfinishLoopが全く呼び出されませんでした。しかし、私は "performSelectorOnMainThread"行にエラーがないので、何が間違っているのか分かりません。
UIを停止せずに一時停止する別のスレッドを設定する正しい方法を説明してくれている人に感謝します(「ホテルが更新されました」などのテキストを表示できるようにするか、プレースメントがフリーズすることはありません)、更新が完了した後でUIを一時停止します。これはかなりの間今の痛みだったので、事前にありがとうございました。
これはいいようですが、スレッドが終了したら何かを正しく呼び出す方法がわかりません。それはシミュレータ上で動作するようですが、iTunesからダウンロードした後ではありません。 – James
さて、ステップ1では、そのすべての 'detachNewThreadSelector:'を使用していません。このような状況がグランドセントラルディスパッチに恵まれている理由です。そのため、スレッドが終了したときにメインスレッドで何かを呼び出すことが非常に簡単になります。 – matt
さて、 "myqueue"変数の設定方法がわかりませんでしたが、 'dispatch_queue_t my_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT、0);'のように設定しました。最初のキューに入るときにエラーは発生しませんが、 'dispatch_async(dispatch_get_main_queue()、^ {')は入力されず、その間にコードは実行されません。 – James