3

のデリゲートとして機能するカスタム クラスを使用して HTTP GET 要求を行うコントローラーがありますNSURLConnection。がNSURLConnection失敗または終了すると、カスタム クラスはコントローラーのメソッドを呼び出しNSData、受信したデータのオブジェクトを渡します。

動作中のコントローラが動的に作成され、ナビゲーション コントローラのスタックにプッシュされるという問題が発生しています。このコントローラーは、そのviewDidLoadメソッドで HTTP GET 要求を行います。ユーザーがナビゲーション バーの [戻る] をすばやく押すと、このコントローラーの割り当てが解除されます。HTTP GET リクエストが終了する前にこれが発生すると、結果のNSURLConnectionコールバックは解放されたオブジェクトへのメソッド呼び出しになり、EXC_BAD_ACCESS になります。

NSURLConnections実際には既に割り当てが解除されている可能性があるコントローラーによって開始された保留中をクリーンアップするための最良の方法は何ですか?

いくつかのNSLogステートメントを挿入しましたが、デリゲートとして使用されているカスタム クラスが実際にはメッセージNSURLConnectionを受信して​​いないようです。deallocこのクラスのコントローラーのインスタンスを nil in に設定しviewDidUnload、 release も呼び出すようにしましたが、それでもコントローラーよりも長く生きているようです。

4

3 に答える 3

2

私が正しく理解している場合は、viewDidUnloadまたはdeallocメソッドで[whateverConnectioncancel]を実行する必要があります。これにより、接続がキャンセルされます。たとえば、NSURLConnectionを使用する大きな画像のカスタムダウンローダーオブジェクトがある場合も、ほぼ同じです。クラスのcancelメソッド(接続をキャンセルして解放する)を作成し、コントローラーのdeallocメソッドで呼び出します。また、wasCanceledなどのboolフラグを使用し、cancelメソッドからwasCanceledが設定されている場合は、カスタムオブジェクトのデリゲートからメソッドを呼び出さないでください。(デリゲートへのポインタは弱いので、他のオブジェクトがcancelメソッドを呼び出したときにすでに解放されている可能性があります)。カスタムオブジェクトのデリゲートはViewControllerであると想定しています。私はこのようなダウンローダーをいくつか持っていました、そしてそれはうまくいきました、

@interface CompaniesDownloader : NSObject /*<NSXMLParserDelegate>*/
{
    id<CompaniesDownloaderDelegate> delegate; //a view controller is the delegate
    NSMutableArray *companies;

    BOOL isWorking;    
    BOOL wasCanceled;   

    @private

    //url connection object
    NSURLConnection *companiesConnection;

    //this is where i put the binary data that gets transformed into xml
    NSMutableData *webData;

    //temporary string used when parsing xml
    NSMutableString *tmpString;

    //temporary company used when parsing xml
    Company *tmpCompany;
}

実装では:

-(void) cancel
{
  [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: FALSE];

  wasCanceled = TRUE;
  [companiesConnection cancel];
  [webData release];
  webData = nil;
  self.companiesConnection = nil; //OR [companiesConnection release]; companiesConnection=nil;
  isWorking = FALSE;
}
于 2010-09-08T10:50:46.060 に答える
0

リクエストを行うときはView Controllerを保持し、getリクエストが終了したら解放する必要があります

YourViewController.m
- (void)callGetRequest {
   [self retain];
}

- (void)didFinishAllGetTask {
   [self release];
}
于 2010-09-08T06:55:50.047 に答える
0

ユーザーがナビゲーション バーの [戻る] をすばやく押すと、このコントローラーの割り当てが解除されます。HTTP GET リクエストが終了する前にこれが発生した場合、結果の NSURLConnection コールバックは、解放されたオブジェクトへのメソッド呼び出しになり、EXC_BAD_ACCESS になります。

ユーザーが戻るボタンを押したら、View Controller クラスをそのオブジェクトのデリゲートとして登録解除します。(View Controller クラス内のオブジェクトへの参照を保持して、次のようなことができるようにしますsomeObject.delegate = nil;)。ビューコントローラーのdeallocメソッドでそれを行うことができます。

于 2010-09-08T07:13:04.483 に答える