1

アプリのネットワーク コードを一元化しようとしています。基本的に、サーバーからの情報が必要なさまざまな場所で、ServerRequest クラスのオブジェクト serverRequest を作成して情報を取得します。ServerRequest が完了すると、情報を呼び出し元のオブジェクトに送り返す必要があります。もちろん、非同期で動作する必要があります。待機中にアプリが停止することは望ましくありません。

この情報の戻りは、注意が必要な部分です。私のオプションは委任と通知のようです。私が知る限り、どちらにも問題があります。

委任: serverRequest オブジェクトへの委任として自分自身を渡します。問題は、リクエストが完了する前に割り当てが解除された場合、serverRequest が割り当て解除されたオブジェクトをメッセージで送信し、プログラムがクラッシュすることです。これを防ぐには、すべてのサーバー リクエスト (複数ある場合もあります) を追跡し、dealloc メソッドでそれらすべてを通知して、それ以上メッセージを受信しないようにする必要があります。これはすべて可能ですが、確かに面倒です。

通知: 情報を渡すのは大変な作業のようです。自分自身をオブザーバーとして通知センターに追加し、割り当てを解除するときに自分自身を削除する必要があります。さらに、完了時にどのような通知を投稿するかという情報を ServerRequest に渡す必要があります。そして、ServerRequest は受信したデータを NSDictionary に押し込む必要があり、それが渡された後にそれを元に戻します。

どちらのメソッドも機能するはずですが、ServerRequest を呼び出すコードを起動してオブジェクトを渡すだけでも、非常に手間がかかるように思えます。通知はもう少し柔軟で、痛みが少なく、クラッシュする可能性が少し低いと思いますが、どちらのアプローチにもあまり満足していません. フィードバックをいただければ幸いです。ありがとう。

4

4 に答える 4

1

リストアプローチを使用します。すべてのリクエストを追跡する NSMutableArray を含む requestController を用意するだけです。これの利点は、コントローラの割り当てが解除されたときに、[requests makeObjectsPerformSelector: @selector(cancelRequest)] のようなことを実行して、これらすべてのリクエストがネットワークを独占するのを防ぐことができることです。また、デバッグにも役立ちます。各オブジェクトに保留中のリクエストを実際に問い合わせたり、多くの保留中のリクエストのパフォーマンスへの影響を測定したりできるためです。リクエストが終了すると、リクエストコントローラーに通知され、簡単な操作でリストから削除できます。オブジェクトを削除します。

また、誰かがあなたのオブジェクトを所有する必要があります。手動で管理されたメモリでは、ObjC オブジェクトはそれ自体を保持できますが、GC に移行したい場合は、浮動オブジェクトを CFRetaining するよりも配列を使用する方がはるかにクリーンなソリューションです。

于 2010-01-17T14:16:26.517 に答える
0

代理人を保持するべきではありません。メッセージを送信する前に、有効なデリゲートオブジェクトを確認するを参照してください。

于 2010-01-16T23:11:29.673 に答える
0

渡されたデリゲートを保持でき、サーバー要求も終了するまで割り当てが解除されません。

例えば

@interface ServerRequest : NSObject
{
  id delegate;
}

@property (retain) id delegate;
@end

@implementation ServerRequest
@synthesize delegate;
@end

ただし、ServerRequestをもう一方の端から解放しないようにする必要があります。そうしないと、ServerRequestのイニシエーターが、それ自体が解放されたときに解放することができ、問題が解消されます。それをするために

@interface SomeObject : NSObject
{
  ServerRequest getsomedata;
}

@property (retain) ServerRequest getsomedata;
@end

- (void)f()
{
  [self setGetsomedata:[[ServerRequest alloc] init]];
  [[self getsomedata] release]; // take away the refcount from allocating, setting the property will retain
}
于 2010-01-16T23:07:27.183 に答える
0

私は過去に同様の問題に遭遇しましたが、わずかに異なるデザインを選択しました(@uliwitnessが提案したものと同様です。

リクエスト(つまり実際のコンテンツ)を配信システムから分離することを選択します。あなたの場合、serverRequestはリクエストのコンテンツ(URL、データなど)を保持しますが、サーバーとの実際の通信は行いません。サーバーリクエストのデリゲートはシングルトンCommLayerクラスであり、実際にリクエストの送信、受信、およびリクエストの完了についてのデリゲートへの通知を処理します。

したがって、serverRequestを送信するには、[CommLayer sendRequest:serverRequest withDelegate:myDelegate]のようなものを呼び出します。

これで、CommLayerはserverRequestではなくデリゲートを保持する実際のクラスになり、[CommLayer removeDelegate:myDelegate]のようなものを使用して、クラスが無効になったことをいつでもCommLayerに通知できます。

確かにそれはより多くの作業ですが、いくつか例を挙げると、この設計から実際に多くの利点が得られます。

  • ネットワークトラフィックの実際の管理。一度に必要なオープン接続の数を決定し、リクエストをキューに入れることができます。
  • 不要なリクエストはキャンセルできます
于 2010-01-18T10:30:13.467 に答える