NSURLRequest 自动释放:崩溃

Posted

技术标签:

【中文标题】NSURLRequest 自动释放:崩溃【英文标题】:NSURLRequest autorelease: crash 【发布时间】:2010-11-01 22:45:53 【问题描述】:

我在释放 NSMutableURLRequest 对象时遇到问题。 请求对象释放期间应用程序崩溃。

对象是通过 [[NSMutableURLRequest alloc] initWithURL:my_http_url]; 创建的;

作为主流的控制流,我尝试释放连接对象以响应 connectionDidFinishLoading 处理程序被调用。

起初我尝试在 connectionDidFinishLoading 处理程序中自动释放 NSMutableURLRequest。这导致了崩溃,所以我认为这可能是因为连接类在调用 connectionDidFinishLoading 之前在内部推送了自动释放池,并且仍然希望在处理程序返回时连接对象是有效的,因此不可能在 connectionDidFinishLoading 中释放或自动释放连接对象。

如果我根本不释放 NSMutableURLRequest,根据 Instruments 的说法,它会以引用计数 1 泄漏。

因此,我决定通过触发自动释放 NSMutableURLRequest 传递给它的 NSRunLoop 事件来延迟释放。 这仍然会导致崩溃。

调用自动释放前的retainCount 为1。

崩溃堆栈是:

#

0   0x9448aedb in objc_msgSend
#1  0x04a47ce0 in ??
#2  0x02e51501 in HTTPMessage::~HTTPMessage
#3  0x02945621 in _CFRelease
#4  0x02e516a9 in HTTPRequest::~HTTPRequest
#5  0x02e50967 in URLRequest::~URLRequest
#6  0x02945621 in _CFRelease
#7  0x0032fb70 in -[NSURLRequestInternal dealloc]
#8  0x0032fb1a in -[NSURLRequest dealloc]
#9  0x002f27a5 in NSPopAutoreleasePool
#10 0x003b5dd0 in __NSFirePerformTimer
#11 0x0299e8a2 in __CFRunLoopDoObservers
#12 0x0296a39e in CFRunLoopRunSpecific
#13 0x0296a048 in CFRunLoopRunInMode
#14 0x031d289d in GSEventRunModal
#15 0x031d2962 in GSEventRun
#16 0x0058ede1 in UIApplicationMain
#17 0x00002b9c in main at main.m:14

感谢您的建议。

【问题讨论】:

retainCount 永远不会下降到零,所以这不是非常有用的信息。 Instruments 始终是查看对象的保留/释放/自动释放历史记录的更好方法。 【参考方案1】:

使用NSDebugEnabled/NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled后发现问题:

结果

http_url = [NSURL URLWithString:...]

应该被保留或不自行自动释放。

【讨论】:

【参考方案2】:

尝试使用以下方法将其实例化为自动释放的对象:

[NSMutableURLRequest requestWithURL:my_http_url];

【讨论】:

【参考方案3】:

我相信在这种情况下,仪器对于任何追踪都没有用,因为 应用程序崩溃然后自动重启(它是 iPad/iPhone 应用程序),所以所有 乐器历史已不复存在。 我看不出将 NSMutableURLRequest 实例化为自动释放对象的意义 因为它需要在跨越多个的异步调用期间保留 空闲循环周期。 NSURLConnection 可以在内部保留它,也可以不保留,但保留 额外的安全参考不应该受到伤害。 初始化代码基本上归结为以下内容:

rq->url_encoded = [url_encode(rq->url) 保留]; rq->http_url = [NSURL URLWithString:rq->url_encoded]; rq->http_request = [[NSMutableURLRequest alloc] initWithURL:rq->http_url]; [rq->http_request setHTTPMethod:@"GET"]; NSArray* availableCookies = [rq->service.CookieJar cookiesForURL:rq->http_url]; NSDictionary* 标头 = [NSHTTPCookie requestHeaderFieldsWithCookies:availableCookies]; [rq->http_request setAllHTTPHeaderFields:headers]; rq->http_connection = [NSURLConnection alloc]; [rq->http_connection initWithRequest:rq->http_request 委托:rq startImmediately:YES];

释放过程是connectionDidFinishLoading调用[rq->http_connection cancel] 和 [rq autorelease],后者最终导致:

// [http_request 自动释放]; // delayAutoRelease(http_request); [http_connection 自动释放]; [http_url 自动释放]; [网址发布]; [url_encoded 发布]; [回复发布];

请注意,[response release] 只是将先前在 didReceiveResponse 中执行的 [response retain] 配对。

如果我将前两行注释掉,NSURLRequest 会泄漏参考 每个仪器计数 1,这是观察到的唯一泄漏。 每当我尝试以上述任何方式自动释放 http_request 时, 发生崩溃。

【讨论】:

不要告诉我们它“归结为”什么,给我们看代码。什么是rq?它是一个 Objective-C 对象的实例吗?它是如何创建的?

以上是关于NSURLRequest 自动释放:崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发网络篇--NSURLConnection

网络请求之GETPOST请求

释放自动释放对象不会使我的应用程序崩溃,为啥?

双重释放自动释放的对象不会崩溃

释放自动释放字符串对象不会崩溃

NSURLRequest 出错,无法识别的选择器发送到实例