Ben Copsey

Start work on cleaning up memory management to fix problems with garbage collection

@@ -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