3

我试图通过下面的方法将块用作API请求的回调。此方法采用嵌套在此方法的块中的块。它的工作原理...但是,回调块中的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 2012-01-08 12:27:43

+0

我发现了这个问题,我完全尴尬的原因是什么。导致泄漏的请求对象是另一个对象的子类。我意识到我实际上忘了在子类中包含[super dealloc]。子类只有一些属性被请求填充,而超级约有15个。对于测试,我在dealloc之前多次运行请求,因此发生了大量泄漏。卫生署! – GnarlyDog 2012-01-08 19:22:50

+1

如果你错过了[超级dealloc],你应该会收到警告,如果你不想检查你的构建设置 – hooleyhoop 2012-01-08 19:58:12

回答

0

根据要求我正在记录这里的结论。事实证明,我忘记了在子类的dealloc方法中调用super dealloc。这导致super在释放后泄漏所有它保留的属性。程序员错误。请注意,这种情况发生在ARC之前。