1. ホーム
  2. objective-c

[解決済み] iOSのBackground Threadの起動

2022-09-02 07:40:10

質問

iOSデバイスに小さなsqlitedbを持っています。ユーザーがボタンを押すと、sqliteからデータを取得し、それをユーザーに表示します。

このフェッチ部分は、バックグラウンドスレッドで行いたいと思います(UIメインスレッドをブロックしないため)。私はこれを次のように行います。

[self performSelectorInBackground:@selector(getResultSetFromDB:) withObject:docids];

フェッチ&アンプ;少し処理した後、私はUIを更新する必要があります。しかし、(グッドプラクティスとして)バックグラウンドスレッドからUI更新を行うべきではありません。私は selector をメインスレッドで呼び出します。

[self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];

しかし、私のアプリは最初のステップ、すなわちバックグラウンドスレッドを開始するところでクラッシュします。これはiOSでバックグラウンドスレッドを開始する方法ではないのでしょうか?

UPDATE 1: その後 [self performSelectorInBackground.... 私はこのスタックトレースを取得し、これまで何の情報もない - 。

アップデイト2。 バックグラウンドスレッドを立ち上げて、こんな感じにしてみました。 [NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids]; しかし、まだ私は同じスタックトレースを取得します。

はっきりさせておきたいのですが、メインスレッドでこの操作を実行すると、すべてがスムーズに実行されます...

アップデイト3 これは私がバックグラウンドから実行しようとしているメソッドです。

- (void)getResultSetFromDB:(NSMutableArray *)toProceessDocids
{
    SpotMain *mirror = [[SpotMain alloc] init];
    NSMutableArray *filteredDocids = toProceessDocids;

    if(![gMediaBucket isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForMediaBucketWithDocID:filteredDocids mBucket:gMediaBucket numRes:-1];
    if(![gMediaType isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForMediaType:filteredDocids mediaType:gMediaType numRes:-1];
    if(![gPlatform isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForPlatformID:filteredDocids platformId:@"1" numRes:-1];

    self.resultSet = [mirror FetchObjectFromDocid:filteredDocids];
    [filteredDocids release];
    [mirror release];

    [self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];
    return;
}

どのように解決するのですか?

もし performSelectorInBackground:withObject: を使って新しいスレッドを生成する場合、実行されたセレクタは新しいスレッドの自動解放プール、実行ループ、その他の設定の詳細を設定する責任を負います - 詳しくは NSObject を使用してスレッドを生成する」を参照してください。 を参照してください。 スレッド プログラミング ガイド .

おそらく グランド・セントラル・ディスパッチ を使ったほうがいいでしょうね。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self getResultSetFromDB:docids];
});

GCDは新しい技術で、メモリのオーバーヘッドとコード行数の点でより効率的です。


更新 に脱帽。 クリス・ノレット は、上記のコードをよりシンプルにし、Apple の最新の GCD コード例を維持するための変更を提案しました。