Permalink
Browse files

Fix a memory usage error. Also add a test to verify that handler is r…

…eleased on queue, and catch any other memory errors like the one I had left in previously.
  • Loading branch information...
1 parent 046fd64 commit 2bc5961b3c7a97ed1459661073b70072f984b619 @adamjernst committed Oct 12, 2011
View
2 AEURLConnection/AEURLConnection.m
@@ -42,7 +42,7 @@ + (void)sendAsynchronousRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler {
AEURLConnectionRequest *req = [[AEURLConnectionRequest alloc] initWithRequest:request queue:queue completionHandler:handler];
[[AEURLConnectionManager sharedManager] startRequest:req];
- [request release];
+ [req release];
}
@end
View
4 Example/AEURLExample.xcodeproj/project.pbxproj
@@ -21,9 +21,7 @@
C4C186AF1445FF9C003DBCC0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C4C186AD1445FF9C003DBCC0 /* InfoPlist.strings */; };
C4C186B21445FF9C003DBCC0 /* AEURLExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C186B11445FF9C003DBCC0 /* AEURLExampleTests.m */; };
C4C186C31445FFD7003DBCC0 /* AEURLConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C186C21445FFD7003DBCC0 /* AEURLConnection.m */; };
- C4C186C41445FFD7003DBCC0 /* AEURLConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C186C21445FFD7003DBCC0 /* AEURLConnection.m */; };
C4C186CB144615CF003DBCC0 /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C186CA144615CF003DBCC0 /* JSONKit.m */; };
- C4C186CC144615CF003DBCC0 /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C186CA144615CF003DBCC0 /* JSONKit.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -292,8 +290,6 @@
buildActionMask = 2147483647;
files = (
C4C186B21445FF9C003DBCC0 /* AEURLExampleTests.m in Sources */,
- C4C186C41445FFD7003DBCC0 /* AEURLConnection.m in Sources */,
- C4C186CC144615CF003DBCC0 /* JSONKit.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
83 Example/AEURLExampleTests/AEURLExampleTests.m
@@ -7,26 +7,83 @@
//
#import "AEURLExampleTests.h"
+#import "AEURLConnection.h"
+
+// This object simulates UIViewController, which can only be released on the
+// main thread. (This is the root of "The Deallocation Problem"; search the
+// web for more.)
+@interface AEMainThreadReleaseOnlyObject : NSObject {
+ BOOL *gotResponse;
+ BOOL *dealloced;
+ BOOL *deallocedOnMainThread;
+}
+- (id)initWithGotResponse:(BOOL *)g dealloced:(BOOL *)d onMainThread:(BOOL *)main;
+- (void)handleResponse:(NSURLResponse *)response;
+@end
@implementation AEURLExampleTests
-- (void)setUp
-{
- [super setUp];
-
- // Set-up code here.
+- (void)testMainThreadReleaseOnlyObject {
+ NSAssert([NSThread isMainThread], @"Expected unit test to run on main thread");
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]
+ cachePolicy:NSURLRequestUseProtocolCachePolicy
+ timeoutInterval:20.0];
+
+ BOOL gotResponse = NO;
+ BOOL dealloced = NO;
+ BOOL deallocedOnMainThread = NO;
+ AEMainThreadReleaseOnlyObject *obj;
+ obj = [[AEMainThreadReleaseOnlyObject alloc] initWithGotResponse:&gotResponse
+ dealloced:&dealloced
+ onMainThread:&deallocedOnMainThread];
+
+ [AEURLConnection sendAsynchronousRequest:request
+ queue:[NSOperationQueue mainQueue]
+ completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
+ [obj handleResponse:response];
+ }];
+ [obj release];
+ NSAssert(!dealloced, @"Object shouldn't be dealloced yet; should be dealloced during running of runloop");
+
+ int runs = 0;
+ while (dealloced == NO && runs < 20) {
+ NSLog(@"Running main run loop since object isn't deallocated yet");
+ [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
+ runs++;
+ }
+
+ if (!gotResponse) {
+ STFail(@"Completion handler never called, although timeout should have expired so we should have received response or error");
+ } else if (!dealloced) {
+ STFail(@"Object captured in completion handler was never released");
+ } else if (!deallocedOnMainThread) {
+ STFail(@"Main-thread-release-only object was dealloced, but not on main thread");
+ }
+}
+
+@end
+
+
+@implementation AEMainThreadReleaseOnlyObject
+
+- (id)initWithGotResponse:(BOOL *)g dealloced:(BOOL *)d onMainThread:(BOOL *)main {
+ if (self = [super init]) {
+ gotResponse = g;
+ dealloced = d;
+ deallocedOnMainThread = main;
+ }
+ return self;
}
-- (void)tearDown
-{
- // Tear-down code here.
-
- [super tearDown];
+- (void)dealloc {
+ *deallocedOnMainThread = [NSThread isMainThread];
+ *dealloced = YES;
+ [super dealloc];
}
-- (void)testExample
-{
- STFail(@"Unit tests are not implemented yet in AEURLExampleTests");
+- (void)handleResponse:(NSURLResponse *)response {
+ *gotResponse = YES;
}
@end

0 comments on commit 2bc5961

Please sign in to comment.