The basics are I have a custom NSURLProtocol
. In startLoading
, [self client]
is of type:
<_NSCFURLProtocolBridge> {NSURLProtocol, CFURLProtocol}
The problem is running this in a garbage-collected environment. Because I'm writing a screensaver, I'm forced to make it garbage-collected. However, the _NSCFURLProtocolBridge protocol seems to always throw:
malloc: reference count underflow for (memory_id_here), break on auto_refcount_underflow_error to debug
An example dump to the debug console is:
ScreenSaverEngine[1678:6807] client is <_NSCFURLProtocolBridge 0x20025ab00> {NSURLProtocol 0x200258ec0, CFURLProtocol 0x20029c400}
ScreenSaverEngine(1678,0x102eda000) malloc: reference count underflow for 0x20025ab00, break on auto_refcount_underflow_error to debug.
You can see that the underflow occurs for <_NSCFURLProtocolBridge 0x20025ab00>
.
When I break on auto_refcount_underflow_error
, it seems to stack-trace back up to URLProtocolDidFinishLoading:
in:
id client = [self client];
...
[client URLProtocolDidFinishLoading:self];
This problem seems to have existed for a while, but there seems to be no answer at all online:
http://lists.apple.com/archives/cocoa-dev/2008/May/msg01272.html http://www.cocoabuilder.com/archive/message/cocoa/2007/12/17/195056
The bug only shows itself in garbage-collected environments for these listed bugs as well. Any thoughts on how I can work around this without causing memory issues? I'm assuming this probably has something to do with the CF type underneath NSURLProtocol being released improperly?
Last WWDC we confirmed this bug with a webkit engineer, he could see the bug right there in the code so hopefully they'll fix it. The workaround is to CFRetain the client in the initWithRequest method.
- (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id <NSURLProtocolClient>)client
{
// work around for NSURLProtocol bug
// note that this leaks!
CFRetain(client);
if (self = [super initWithRequest:request cachedResponse:cachedResponse client:client])
{
}
return self;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With