3

私は、以下の方法でAPIリクエストのコールバックとしてブロックを使用しようとしています。このメソッドは、このメソッドのブロックにネストされたBlockを受け取ります。それは動作します... BUT、コールバックブロックのNSJSONSerializationリーク

このメソッドを呼び出したオブジェクトが解放されると、NSJSONSerializationは大量のメモリリークをダンプします。すべてが動いている間は、それはすべていいです。リークは、要求オブジェクトがなくなった後にのみ発生します。リークは、ほぼすべてのNSPlaceHolderタイプです。

私は私の知恵の終わりであり、どんなアイデアも大歓迎です!

- (void)sendRequestUsingNSURLConnectionWith:(NSURLRequest *)request andCallback:(void (^)(id))handler 
     { 
      __block __typeof__(self)blockSelf = self; 

      // CL: build a block to be run asynchronously 
      ApiClientCallback handleResponse = [[^(NSURLResponse *response, NSData *data, NSError *error) { 

       id results = nil; 

       // CL: http errors would be caught here. 
       if (error) { 
        NSLog(@"[%@ %@] HTTP error: %@", NSStringFromClass([blockSelf class]), NSStringFromSelector(_cmd), error.localizedDescription); 
        results = error; 
       } 
       else { 
       // CL: parse the JSON 
        NSError *jsonError = nil; 
        NSError *apiError = nil; 
        if (data) { 
         results = [NSJSONSerialization JSONObjectWithData:data 
                    options:NSJSONReadingMutableContainers 
                    error:&jsonError]; 
        } 
        else { 
         results = nil; 
        } 
        // CL: json errors would be caught here. 
        if (jsonError) { 
         NSLog(@"[%@ %@] JSON error: %@", NSStringFromClass([blockSelf class]), NSStringFromSelector(_cmd), error.localizedDescription); 
         results = error; 
        } 
        // CL: Check for API errors. 
        else if ([blockSelf checkApiErrorCode:results error:&apiError]) { 
         //CL: if there's an error make the NSError object the result. 
         if (apiError) results = apiError; 
        } 
       } 
       // CL: Send result to the completion block of the requesting object 
       handler(results); 

      } copy] autorelease]; 

      [NSURLConnection sendAsynchronousRequest:request 
               queue:self.opQueue 
            completionHandler:handleResponse]; 
     } 
+1

「NSJSONSerializationが大量のメモリリークをダンプする」ことを説明してください。 – hooleyhoop

+0

私はこの問題を発見しましたが、その原因が完全に恥ずかしいです。リークの原因となった要求オブジェクトは、別のオブジェクトのサブクラスでした。サブクラスに[super dealloc]を含めるのを実際に忘れてしまったことに気付きました。サブクラスには、要求によって満たされているいくつかのプロパティがあり、スーパーには約15があります。テストのために、私はdeallocの前に何度も要求を実行していました。ドー! – GnarlyDog

+1

ビルドの設定を確認したくない場合は、[super dealloc]が見つからない場合に警告が表示されます。 – hooleyhoop

答えて

0

リクエストごとにここで結論を文書化しています。サブクラスのdeallocメソッドでスーパーdeallocを呼び出すことを忘れていたことが判明しました。これにより、割り当て解除時にスーパーがすべてのリークプロパティーをリークさせました。プログラマーエラー。このシナリオはプリARCで発生していたことに注意してください。