回调块中的 NSJSONSerialization 泄漏

发布于 2024-12-25 15:19:50 字数 2453 浏览 4 评论 0原文

我尝试通过以下方法使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

给妤﹃绝世温柔 2025-01-01 15:19:50

根据要求,我在这里记录了结论。原来是我忘记在子类的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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文