NSJSONSerialization утечки в блоке обратного вызова - PullRequest
3 голосов
/ 08 января 2012

Я пытаюсь использовать блоки в качестве обратных вызовов для запроса 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];
        }

1 Ответ

0 голосов
/ 19 февраля 2014

По запросу я документирую заключение здесь.Оказалось, что я забыл вызвать super dealloc в методе dealloc подкласса.Это привело к тому, что супер утратил все свои сохраненные свойства при освобождении.Ошибка программиста.Обратите внимание, что этот сценарий происходил до ARC.

...