回调块中的 NSJSONSerialization 泄漏
我尝试通过以下方法使用 Blocks 作为 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];
}
I'm trying to use Blocks as callbacks for an API request via the method below. This method takes a Block that is nested in this method's Block. It works... BUT,
If an Object that has called this method is dealloced, NSJSONSerialization dumps out a massive memory leak. It's all good while everything is running. The leak only happens after the requesting object is gone. The leaks are nearly all NSPlaceHolder types.
I'm at my wits end and any ideas are greatly appreciated!
- (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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据要求,我在这里记录了结论。原来是我忘记在子类的dealloc方法中调用super dealloc了。这导致超级在释放时泄漏了其所有保留的属性。程序员错误。请注意,这种情况发生在 ARC 之前。
Per request I'm documenting the conclusion here. It turned out that I had forgotten to call super dealloc in the dealloc method of a sub class. This caused the super to leak all of it's retained properties upon deallocation. Programmer error. Note that this scenario was happening pre ARC.