3

以下のメソッドを使用して、APIリクエストのコールバックとしてブロックを使用しようとしています。このメソッドは、このメソッドのブロックにネストされているブロックを取ります。それは動作します...しかし、

このメソッドを呼び出したオブジェクトの割り当てが解除されると、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];
        }
4

1 に答える 1

0

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

于 2014-02-19T04:24:30.683 に答える