Start work on cleaning up memory management to fix problems with garbage collection
Showing
1 changed file
with
19 additions
and
36 deletions
| @@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
| 24 | #import "ASIDataCompressor.h" | 24 | #import "ASIDataCompressor.h" |
| 25 | 25 | ||
| 26 | // Automatically set on build | 26 | // Automatically set on build |
| 27 | -NSString *ASIHTTPRequestVersion = @"v1.7-100 2010-10-03"; | 27 | +NSString *ASIHTTPRequestVersion = @"v1.7-101 2010-10-03"; |
| 28 | 28 | ||
| 29 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 29 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
| 30 | 30 | ||
| @@ -582,12 +582,13 @@ static NSOperationQueue *sharedQueue = nil; | @@ -582,12 +582,13 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 582 | [self setComplete:YES]; | 582 | [self setComplete:YES]; |
| 583 | [self cancelLoad]; | 583 | [self cancelLoad]; |
| 584 | 584 | ||
| 585 | - [[self retain] autorelease]; | 585 | + CFRetain(self); |
| 586 | [self willChangeValueForKey:@"isCancelled"]; | 586 | [self willChangeValueForKey:@"isCancelled"]; |
| 587 | cancelled = YES; | 587 | cancelled = YES; |
| 588 | [self didChangeValueForKey:@"isCancelled"]; | 588 | [self didChangeValueForKey:@"isCancelled"]; |
| 589 | 589 | ||
| 590 | [[self cancelledLock] unlock]; | 590 | [[self cancelledLock] unlock]; |
| 591 | + CFRelease(self); | ||
| 591 | } | 592 | } |
| 592 | 593 | ||
| 593 | - (void)cancel | 594 | - (void)cancel |
| @@ -1265,7 +1266,7 @@ static NSOperationQueue *sharedQueue = nil; | @@ -1265,7 +1266,7 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 1265 | 1266 | ||
| 1266 | - (void)setStatusTimer:(NSTimer *)timer | 1267 | - (void)setStatusTimer:(NSTimer *)timer |
| 1267 | { | 1268 | { |
| 1268 | - [self retain]; | 1269 | + CFRetain(self); |
| 1269 | // We must invalidate the old timer here, not before we've created and scheduled a new timer | 1270 | // We must invalidate the old timer here, not before we've created and scheduled a new timer |
| 1270 | // This is because the timer may be the only thing retaining an asynchronous request | 1271 | // This is because the timer may be the only thing retaining an asynchronous request |
| 1271 | if (statusTimer && timer != statusTimer) { | 1272 | if (statusTimer && timer != statusTimer) { |
| @@ -1273,7 +1274,7 @@ static NSOperationQueue *sharedQueue = nil; | @@ -1273,7 +1274,7 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 1273 | [statusTimer release]; | 1274 | [statusTimer release]; |
| 1274 | } | 1275 | } |
| 1275 | statusTimer = [timer retain]; | 1276 | statusTimer = [timer retain]; |
| 1276 | - [self release]; | 1277 | + CFRelease(self); |
| 1277 | } | 1278 | } |
| 1278 | 1279 | ||
| 1279 | // This gets fired every 1/4 of a second to update the progress and work out if we need to timeout | 1280 | // This gets fired every 1/4 of a second to update the progress and work out if we need to timeout |
| @@ -1692,6 +1693,7 @@ static NSOperationQueue *sharedQueue = nil; | @@ -1692,6 +1693,7 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 1692 | 1693 | ||
| 1693 | #pragma mark talking to delegates | 1694 | #pragma mark talking to delegates |
| 1694 | 1695 | ||
| 1696 | + | ||
| 1695 | /* ALWAYS CALLED ON MAIN THREAD! */ | 1697 | /* ALWAYS CALLED ON MAIN THREAD! */ |
| 1696 | - (void)requestStarted | 1698 | - (void)requestStarted |
| 1697 | { | 1699 | { |
| @@ -1764,6 +1766,15 @@ static NSOperationQueue *sharedQueue = nil; | @@ -1764,6 +1766,15 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 1764 | } | 1766 | } |
| 1765 | } | 1767 | } |
| 1766 | 1768 | ||
| 1769 | +/* ALWAYS CALLED ON MAIN THREAD! */ | ||
| 1770 | +- (void)passReceivedDataToDelegate:(NSData *)data | ||
| 1771 | +{ | ||
| 1772 | + if (delegate && [delegate respondsToSelector:didReceiveDataSelector]) { | ||
| 1773 | + [delegate performSelector:didReceiveDataSelector withObject:self withObject:data]; | ||
| 1774 | + return; | ||
| 1775 | + } | ||
| 1776 | +} | ||
| 1777 | + | ||
| 1767 | // Subclasses might override this method to perform error handling in the same thread | 1778 | // Subclasses might override this method to perform error handling in the same thread |
| 1768 | // If you do this, don't forget to call [super failWithError:] to let the queue / delegate know we're done | 1779 | // If you do this, don't forget to call [super failWithError:] to let the queue / delegate know we're done |
| 1769 | - (void)failWithError:(NSError *)theError | 1780 | - (void)failWithError:(NSError *)theError |
| @@ -1816,10 +1827,7 @@ static NSOperationQueue *sharedQueue = nil; | @@ -1816,10 +1827,7 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 1816 | // "markAsFinished" will be at the start of main() when we are started | 1827 | // "markAsFinished" will be at the start of main() when we are started |
| 1817 | return; | 1828 | return; |
| 1818 | } | 1829 | } |
| 1819 | - // markAsFinished may well cause this object to be dealloced | ||
| 1820 | - [self retain]; | ||
| 1821 | [self markAsFinished]; | 1830 | [self markAsFinished]; |
| 1822 | - [self release]; | ||
| 1823 | } | 1831 | } |
| 1824 | 1832 | ||
| 1825 | #pragma mark parsing HTTP response headers | 1833 | #pragma mark parsing HTTP response headers |
| @@ -2634,14 +2642,10 @@ static NSOperationQueue *sharedQueue = nil; | @@ -2634,14 +2642,10 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 2634 | 2642 | ||
| 2635 | - (void)handleNetworkEvent:(CFStreamEventType)type | 2643 | - (void)handleNetworkEvent:(CFStreamEventType)type |
| 2636 | { | 2644 | { |
| 2637 | - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||
| 2638 | - [[self retain] autorelease]; | ||
| 2639 | - | ||
| 2640 | [[self cancelledLock] lock]; | 2645 | [[self cancelledLock] lock]; |
| 2641 | 2646 | ||
| 2642 | if ([self complete] || [self isCancelled]) { | 2647 | if ([self complete] || [self isCancelled]) { |
| 2643 | [[self cancelledLock] unlock]; | 2648 | [[self cancelledLock] unlock]; |
| 2644 | - [pool release]; | ||
| 2645 | return; | 2649 | return; |
| 2646 | } | 2650 | } |
| 2647 | 2651 | ||
| @@ -2689,17 +2693,6 @@ static NSOperationQueue *sharedQueue = nil; | @@ -2689,17 +2693,6 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 2689 | } else if ([self downloadComplete] && [self authenticationNeeded]) { | 2693 | } else if ([self downloadComplete] && [self authenticationNeeded]) { |
| 2690 | [self attemptToApplyCredentialsAndResume]; | 2694 | [self attemptToApplyCredentialsAndResume]; |
| 2691 | } | 2695 | } |
| 2692 | - [pool release]; | ||
| 2693 | -} | ||
| 2694 | - | ||
| 2695 | -// This runs on the main thread to run the given invocation on the current delegate | ||
| 2696 | -- (void)invocateDelegate:(NSInvocation *)invocation | ||
| 2697 | -{ | ||
| 2698 | - if (delegate && [delegate respondsToSelector:invocation.selector]) | ||
| 2699 | - { | ||
| 2700 | - [invocation invokeWithTarget:delegate]; | ||
| 2701 | - } | ||
| 2702 | - [invocation release]; | ||
| 2703 | } | 2696 | } |
| 2704 | 2697 | ||
| 2705 | - (void)handleBytesAvailable | 2698 | - (void)handleBytesAvailable |
| @@ -2787,23 +2780,13 @@ static NSOperationQueue *sharedQueue = nil; | @@ -2787,23 +2780,13 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 2787 | // Does the delegate want to handle the data manually? | 2780 | // Does the delegate want to handle the data manually? |
| 2788 | if ([[self delegate] respondsToSelector:[self didReceiveDataSelector]]) { | 2781 | if ([[self delegate] respondsToSelector:[self didReceiveDataSelector]]) { |
| 2789 | 2782 | ||
| 2790 | - | 2783 | + NSData *data = nil; |
| 2791 | - NSMethodSignature *signature = [[[self delegate] class] instanceMethodSignatureForSelector:[self didReceiveDataSelector]]; | ||
| 2792 | - NSInvocation *invocation = [[NSInvocation invocationWithMethodSignature:signature] retain]; | ||
| 2793 | - [invocation setSelector:[self didReceiveDataSelector]]; | ||
| 2794 | - [invocation setArgument:&self atIndex:2]; | ||
| 2795 | - | ||
| 2796 | - NSData *data; | ||
| 2797 | if ([self isResponseCompressed] && ![self shouldWaitToInflateCompressedResponses]) { | 2784 | if ([self isResponseCompressed] && ![self shouldWaitToInflateCompressedResponses]) { |
| 2798 | data = inflatedData; | 2785 | data = inflatedData; |
| 2799 | } else { | 2786 | } else { |
| 2800 | data = [NSData dataWithBytes:buffer length:bytesRead]; | 2787 | data = [NSData dataWithBytes:buffer length:bytesRead]; |
| 2801 | } | 2788 | } |
| 2802 | - [invocation setArgument:&data atIndex:3]; | 2789 | + [self performSelectorOnMainThread:@selector(passReceivedDataToDelegate:) withObject:data waitUntilDone:[NSThread isMainThread]]; |
| 2803 | - [invocation retainArguments]; | ||
| 2804 | - [self performSelectorOnMainThread:@selector(invocateDelegate:) withObject:invocation waitUntilDone:[NSThread isMainThread]]; | ||
| 2805 | - | ||
| 2806 | - | ||
| 2807 | 2790 | ||
| 2808 | // Are we downloading to a file? | 2791 | // Are we downloading to a file? |
| 2809 | } else if ([self downloadDestinationPath]) { | 2792 | } else if ([self downloadDestinationPath]) { |
| @@ -2985,7 +2968,7 @@ static NSOperationQueue *sharedQueue = nil; | @@ -2985,7 +2968,7 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 2985 | - (void)markAsFinished | 2968 | - (void)markAsFinished |
| 2986 | { | 2969 | { |
| 2987 | // Autoreleased requests may well be dealloced here otherwise | 2970 | // Autoreleased requests may well be dealloced here otherwise |
| 2988 | - [self retain]; | 2971 | + CFRetain(self); |
| 2989 | 2972 | ||
| 2990 | // dealloc won't be called when running with GC, so we'll clean these up now | 2973 | // dealloc won't be called when running with GC, so we'll clean these up now |
| 2991 | if (request) { | 2974 | if (request) { |
| @@ -3027,7 +3010,7 @@ static NSOperationQueue *sharedQueue = nil; | @@ -3027,7 +3010,7 @@ static NSOperationQueue *sharedQueue = nil; | ||
| 3027 | }); | 3010 | }); |
| 3028 | } | 3011 | } |
| 3029 | #endif | 3012 | #endif |
| 3030 | - [self release]; | 3013 | + CFRelease(self); |
| 3031 | } | 3014 | } |
| 3032 | 3015 | ||
| 3033 | - (void)useDataFromCache | 3016 | - (void)useDataFromCache |
-
Please register or login to post a comment