Created
January 3, 2011 13:25
-
-
Save yene/763462 to your computer and use it in GitHub Desktop.
Fix for NSURLProtocol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// | |
#import "NSURLProtocol+Fix.h" | |
int main(int argc, char *argv[]) | |
{ | |
[NSURLProtocol fix]; | |
return NSApplicationMain(argc, (const char **) argv); | |
} | |
// | |
// NSURLProtocol+Fix.h | |
// | |
@interface NSURLProtocol (Fix) | |
- (id)fixedInitWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id <NSURLProtocolClient>)client; | |
+ (void)fix; | |
@end | |
// | |
// NSURLProtocol+Fix.m | |
// | |
#import <objc/runtime.h> | |
#import "NSURLProtocol+Fix.h" | |
@implementation NSURLProtocol (Fix) | |
+ (void)fix; | |
{ | |
Class class = [NSURLProtocol class]; | |
Method originalMethod = class_getInstanceMethod(class, @selector(initWithRequest:cachedResponse:client:)); | |
Method categoryMethod = class_getInstanceMethod(class, @selector(fixedInitWithRequest:cachedResponse:client:)); | |
method_exchangeImplementations(originalMethod, categoryMethod); | |
} | |
- (id)fixedInitWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id <NSURLProtocolClient>)client; | |
{ | |
// under GC, and unless we retaint the client, we observe the following issues; | |
// - error messages in the console 'malloc: reference count underflow for XXX, break on auto_refcount_underflow_error to debug.', where XXX is the address of the cient | |
// - crashes on EXC_BAD_ACCESS or exceptions on invocations that could not be done on an object, in both cases indicative of overreleased obejct. The app does not always crash, one needs to hammer it quite hard sometimes | |
// workaround to avoid underflow and crashes | |
// BUT THE OBJECT WILL LEAK!! | |
CFRetain(client); | |
// we exchanged implementation, so lets call the original | |
return [self fixedInitWithRequest:request cachedResponse:cachedResponse client:client]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment