19

UIViewはスレッドセーフではないので、バックグラウンドスレッドにビューを追加できません。これを回避するには、バックグラウンドスレッドにUIViewを作成してから、メインスレッドに追加しても大丈夫ですか?

注:メインスレッドでこれを行わない理由は、実際のコードがはるかに複雑であるため、すべてのビューを作成して値を入力するのに時間がかかるためです。これを行ったときにUIが応答しなくなることを望まないので、これを回避しようとしています。

例えば..

-(void)addLabel//called on background thread
{
    UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0,0,40,100)];
    [label setText:@"example"]
    [self.view performSelector:@selector(addSubview:) onThread:[NSThread mainThread] withObject:example waitUntilDone:YES];
}

前もって感謝します。

4

3 に答える 3

19

UIViewから:

スレッドに関する考慮事項

アプリケーションのユーザー インターフェイスの操作は、メイン スレッドで行う必要があります。したがって、常にアプリケーションのメイン スレッドで実行されているコードから UIView クラスのメソッドを呼び出す必要があります。これが厳密に必要でない唯一の場合は、ビュー オブジェクト自体を作成するときですが、他のすべての操作はメイン スレッドで実行する必要があります。

への呼び出しinitWithFrame:は、明示的にスレッド セーフではありません。への呼び出しsetText:はスレッドセーフではない可能性が高く、「操作」節に該当します。これらは確かにスレッドセーフであると約束されていません。

バックグラウンド スレッドでデータを把握する作業を行います。次に、メイン スレッドでビューを作成します。膨大な数のビューがある場合はdispatch_async()、メイン キューへの複数の呼び出しを使用して作業を分割してみることができます。これにより、UI の応答性が維持される場合があります。私はそれを広範囲に実験していません。

UIView可能な場合は からに切り替えることも検討してCALayerください。ほとんどのCALayer作業はバックグラウンド スレッドで実行できます。膨大な数のビューがある場合、それはおそらく非効率的です。ビューのデータを計算するのに時間がかかるだけの場合は、モデルとビューの情報を適切に分離していないことを示唆しています。モデル クラスは、ビューの作成とは別に、必要なすべてを計算する必要があります。

于 2012-06-20T15:42:13.063 に答える
-1

Drawing and Printing Guide には次のように記載されています。

重要 UIKit クラスは通常、スレッドセーフではありません。すべての描画関連の操作は、アプリケーションのメイン スレッドで実行する必要があります。

したがって、私が理解しているように、唯一の問題は「描画関連の操作」に関連しているようです。正しいクラスがそのメソッドでのみそのような操作を実行すると仮定すると、drawRect:提案したアプローチは問題ないはずです。

于 2012-06-20T15:37:36.933 に答える