2011-01-10 14 views
3

私はObjectiveResource(iOS-> Railsブリッジ)でいくつかのテストを行っています。物事はうまくいくようですが、ライブラリは同期しています(またはそうではないかもしれませんが、the mailing list that supports it is a mess)。performSelectorInBackgroundを使用するリスク?

私は落とし穴がちょうど正常に動作するようです小さなテストで... performSelectorInBackgroundですべてのコールを実行するためにあるが、それは間違っている多くの場合何思ったんだけど。

私が気付いた唯一の注意点は、performSelectorInBackgroundによって呼び出されたメソッドで自動解放プールを作成する必要があることです。drainではなくreleaseを呼び出す必要があります。

答えて

8

performSelectorInBackground:はスレッドの背後でスレッドを使用し、スレッドで大きなものは、競合状態やその他の微妙な地形バグ。これは、明らかに、画面への描画がメインスレッドの外に出ることを意味します。しかし、スレッドセーフではない他の多くのライブラリがあり、これらを使用するコードも汚染されています。

基本的に、スレッドセーフはコードに意図的に入れなければならないもの、またはおそらくそこにないものです。 ObjectiveResourceはそれに対していかなる主張もしていないので、すでに私は緊張しているでしょう。ソースを見ると、スレッドセーフIIRCであるFoundation URL読み込み機構が主に使用されているようです。しかし、ObjectiveResourceコード自体はそうではありません。一見すると、すべてのクラスメソッドは静的変数を使用します。つまり、それらを使用するコードを使用してperformSelectorInBackground:を複数回使用すると、それらはすべて競合条件の対象となります。

Githubの1.1ブランチのように、ConnectionManagerクラスを使って非同期を明示的にサポートしているようです。おそらくこれを使用するほうが良いでしょう(これは本質的に維持されていないコードなので、注意してください)。

+0

その分析のおかげで、@チャック。私は、ObjResourceの問題の原因のひとつは、継承の代わりにカテゴリを使ってすべてをやっているということです。あなたの継承ラインを解放しますが、カテゴリに変数を持てないのでObj-Cを本当に制限しています。とにかく、私はこれをあまりにも多く作っているかもしれないと思う: "ビジネス"アプリ、ブロッキング、同期呼び出しのためにおそらく大丈夫です。 –

+0

バックグラウンドスレッドでUIView部分を作成するのは安全ですが、表示中のビューにそれらを添付しない限りは可能ですか? –

8

実際に問題が発生していますか?または、あなたはそれらを予期していますか?

同じバックグラウンドスレッドからUI要素を更新しようとしない限り、バックグラウンドスレッドで実行しても問題ありません。すべてのUI関連のアクティビティをメインスレッドに転送してください。例えば(擬似):あなたがバックグラウンドスレッド上の任意のインスタンス変数の値を変更している場合、それはあなたが(他のスレッドを防ぐためにselfに同期させることが重要だと

- (void)viewWillAppear:(BOOL)animated { 
    [self performSelectorInBackground:@selector(refreshTableView)]; 
    [super viewWillAppear:animated]; 
} 

- (void)refreshTableView { 
    // Where _listOfObjects is used to populate your UITableView 
    @synchronized(self) { 
     self._listOfObjects = [MyDataType findAllRemote]; 
    } 
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 
} 

注意も(上記のように)メインスレッドのように)更新または設定中に_listOfObjects配列内のオブジェクトにアクセスすることを禁止します。

_listOfObjectsプロパティをatomicと宣言した場合、私は100%肯定的ではないことを心配する必要はありません(私は100%肯定的ではありません)同期ブロック。 ですが、プロパティの値を再割り当てする代わりに、単一の永続インスタンスに変更を加えた場合は、@property宣言にかかわらずsynchronizedブロックが必要になります。 (静的なNSMutableArrayからオブジェクトを追加/削除する)

+0

私は問題を予期していると言います。今すぐRailsサーバーを停止すると、ObjectiveResourceはすぐに間違った応答(エラーを返す代わりにレコード数が0)を返します。私はあなたがオブジェクト自体を調整していない限り、原子は十分であるはずであることに同意します。ああ、バックグラウンドスレッド用の新しいオートリリースプールが必要です。 –

+0

良い点 - 追加のオートリリースプールについて完全に忘れました。 –

+0

エラーに関する私のコメントは間違っていた。それはエラーを返すための仕組みを持っています。 –

関連する問題