Code clean-up for garbage collection
authorWincent Colaiuta <win@wincent.com>
Sat, 11 Aug 2007 13:26:18 +0000 (15:26 +0200)
committerWincent Colaiuta <win@wincent.com>
Sat, 11 Aug 2007 13:26:18 +0000 (15:26 +0200)
I've made a pass through the codebase eliminating message sends that have
effectively been turned into no-ops by the move to garbage collection (retain,
release, autorelease), as well as replacing "release" messages sent to
autorelease pools with "drain", replacing the alloc/init pattern with the
straightforward autoreleased alternative where possible (for brevity),
removing methods that will now never be meaningfully called (dealloc, release,
retainCount etc), and switching some accessors over to synthesized properties
where this enabled me to get rid of no-op retain, release and autorelease
message sends.

I also performed some minor reformatting (better wrapping and column
alignment) where the already-mentioned changes touch code which would benefit
from such reformatting (improved readability); there are still plenty of
places in the codebase where the wrapping could be tweaked to make better use
of the full 132 columns.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
30 files changed:
NOTES.txt
NSMethodSignature+WOTest.m
NSString+WOTest.h
NSString+WOTest.m
NSValue+WOTest.m
Tests/NSObjectTests.m
Tests/WOClassMockTests.m
Tests/WOMockTests.m
Tests/WOMultithreadedCrashTests.m
Tests/WOObjectMockTests.m
Tests/WOProtocolMockTests.m
Tests/WOProtocolStubTests.m
Tests/WOStubTests.m
Tests/WOTestSelfTests.m
WOLightweightRoot.h
WOLightweightRoot.m
WOMock.h
WOMock.m
WOObjectMock.m
WOObjectStub.m
WOProtocolMock.m
WOProtocolStub.m
WOStub.h
WOStub.m
WOTest.h
WOTestApplicationTestsController.m
WOTestBundleInjector.m
WOTestClass.m
WOTestLowLevelException.m
WOTestRunner/WOTestRunner.m

index 10ddcf767bacef430e0dfcbe9c24ebe38776846b..643d5c68b60b6b1c0fca1763ae7c118478fcb3cc 100644 (file)
--- a/NOTES.txt
+++ b/NOTES.txt
@@ -178,7 +178,6 @@ To illustrate how this works, consider the following example. Imagine a tool tha
 - (void)callAppKitMethod
 {
     NSView *aView = [[NSView alloc] initWithFrame:NSZeroRect];
-    [aView release];
 }
 
 By including the AppKit header file you ensure that the compiler doesn't give you any warnings, but if you try to build such code the linker will give you an error that "NSView" is an undefined symbol. Of course, even if you could produce an executable and run it, it wouldn't work because the executable isn't linked to the AppKit.framework. One way to force the framework to load is to set environment variables and then run the product from the command-line. For example, in the bash shell:
@@ -199,7 +198,6 @@ A far more elegant way to solve this problem is to take advantage of the dynamic
     [NSBundle bundleWithPath:@"/System/Library/Frameworks/AppKit.framework"];
     Class   viewClass   = [theBundle classNamed:@"NSView"];
     NSView  *aView      = [[viewClass alloc] initWithFrame:NSZeroRect];
-    [aView release];
 }
 
 No compiler warnings, no linker errors, everything just works. WOTest uses this technique to allow you to load code "on the fly" without having to link to it. All it has to do is look for bundles, load them, and then run the test methods on them.
index 1fa828ad82e503b295dc8f772920640804dbf28a..c136779c6b76bfda3b539ddce09d49d45dd7c0a6 100644 (file)
@@ -107,12 +107,11 @@ See also http://www.stuffonfire.com/2005/12/signaturewithobjctypes_is_stil.html
 
 #ifdef WO_USE_OWN_METHOD_SIGNATURE_IMPLEMENTATION
 
-    return [[[self alloc] initWithObjCTypes:types] autorelease];
+    return [[self alloc] initWithObjCTypes:types];
 
 #else /* use private Apple API */
 
-    NSAssert([self respondsToSelector:@selector(signatureWithObjCTypes:)],
-             @"signatureWithObjCTypes: selector not recognized");
+    NSAssert([self respondsToSelector:@selector(signatureWithObjCTypes:)], @"signatureWithObjCTypes: selector not recognized");
     return [self signatureWithObjCTypes:types];
 
 #endif
index 2a0901ff0d2d774a4f0dfe85d4c17e660d763299..606a3be3d560c96f2a61a0fe65be54824a28b14a 100644 (file)
@@ -36,11 +36,11 @@ void _WOLogv(NSString *format, va_list args);
 
 - (NSString *)WOTest_stringByConvertingToAbsolutePath;
 
-/*! Returns an immutable, autoreleased string created by "collapsing" all of the whitespace in the receiver into single spaces. All newlines are converted into spaces and consecutive spaces are "collapsed" into a single space. */
+/*! Returns an immutable string created by "collapsing" all of the whitespace in the receiver into single spaces. All newlines are converted into spaces and consecutive spaces are "collapsed" into a single space. */
 - (NSString *)WOTest_stringByCollapsingWhitespace;
 
 
-/*! Returns an immutable, autoreleased string created by appending a single character of type unichar to the receiver. */
+/*! Returns an immutable string created by appending a single character of type unichar to the receiver. */
 - (NSString *)WOTest_stringByAppendingCharacter:(unichar)character;
 
 @end
index aa63f02a16354278523d922fc8d754792167b7f4..06e0b0942abf86a58ef3c3ca27f5e2041c5469e3 100644 (file)
@@ -31,7 +31,6 @@ void _WOLog(NSString *format, ...)
     {
         fprintf(stdout, "%s\n", [string UTF8String]);
         fflush(NULL); // flush all open streams (not just stdout)
-        [string release];
     }
     va_end(args);
 }
@@ -44,7 +43,6 @@ void _WOLogv(NSString *format, va_list args)
     {
         fprintf(stdout, "%s\n", [string UTF8String]);
         fflush(NULL); // flush all open streams (not just stdout)
-        [string release];
     }
 }
 
@@ -52,8 +50,7 @@ void _WOLogv(NSString *format, va_list args)
 
 + (NSString *)WOTest_stringWithFormat:(NSString *)format arguments:(va_list)argList
 {
-    return [[[NSString alloc] initWithFormat:format
-                                   arguments:argList] autorelease];
+    return [[NSString alloc] initWithFormat:format arguments:argList];
 }
 
 + (NSString *)WOTest_stringWithCharacter:(unichar)character
@@ -73,9 +70,9 @@ void _WOLogv(NSString *format, va_list args)
 
 - (NSString *)WOTest_stringByCollapsingWhitespace
 {
-    NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
-    NSMutableString *temp = [NSMutableString stringWithString:self];
-    unsigned int length = [temp length];
+    NSCharacterSet  *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
+    NSMutableString *temp       = [NSMutableString stringWithString:self];
+    unsigned int    length      = [temp length];
     for (unsigned int i = 0; i < length; i++)
     {
         if ([whitespace characterIsMember:[temp characterAtIndex:i]])
@@ -93,7 +90,7 @@ void _WOLogv(NSString *format, va_list args)
             }
         }
     }
-    return [NSString stringWithString:temp]; // return immutable, autoreleased
+    return [temp copy]; // return immutable
 }
 
 - (NSString *)WOTest_stringByAppendingCharacter:(unichar)character
index 9bb24c04972ddf9e4b1419a54dc2f3f2522bf6e8..d0232108d9d47eb982b47a18af88cdf3aaf0d280 100644 (file)
         {
             // for NSString objects: just return content
             if ([NSObject WOTest_object:valueContents isKindOfClass:[NSString class]])
-                return [[valueContents retain] autorelease];
+                return valueContents;
             else if ([NSObject WOTest_object:valueContents respondsToSelector:@selector(description)] &&
                      [NSObject WOTest_isIdReturnType:[NSObject WOTest_returnTypeForObject:valueContents
                                                                                  selector:@selector(description)]])
index 62c3603c11cfb1ba8dfc105735148fdd515d4ad9..a1383a3c0ce317fa177508351f7aa9d62cfc4c4b 100644 (file)
@@ -47,7 +47,6 @@
     // custom classes that do not respond to "description" return class name
     WOLightweightRoot *root = [WOLightweightRoot newLightweightRoot];
     WO_TEST_EQ([NSObject WOTest_descriptionForObject:root], @"WOLightweightRoot");
-    [root dealloc];
 
     // special case: NSValues that contain NSStrings should return the string
     NSValue *value = [NSValue WOTest_valueWithObject:@"foo"];
     WO_TEST([NSObject WOTest_object:subobject isKindOfClass:[NSString class]]);
 
     // superclass should not be considered as same kind as subclass
-    WO_TEST_FALSE([NSObject WOTest_object:[[[NSObject alloc] init] autorelease]
-                     isKindOfClass:[self class]]);
+    WO_TEST_FALSE([NSObject WOTest_object:[[NSObject alloc] init] isKindOfClass:[self class]]);
 
     // initial attempt at this test failed because the NSString object had a
     // superclass of "%NSCFString", which happened to match NSMutableString!
     //WO_TEST_FALSE([@"constant string" isKindOfClass:[NSMutableString class]]);
 
     // should handle custom root classes without problems
-    WO_TEST([NSObject WOTest_object:otherObject
-               isKindOfClass:NSClassFromString(@"WOLightweightRoot")]);
+    WO_TEST([NSObject WOTest_object:otherObject isKindOfClass:NSClassFromString(@"WOLightweightRoot")]);
     WO_TEST_FALSE([NSObject WOTest_object:otherObject isKindOfClass:[NSString class]]);
-    WO_TEST_FALSE([NSObject WOTest_object:self
-                     isKindOfClass:NSClassFromString(@"WOLightweightRoot")]);
-
-    // cleanup
-    [otherObject dealloc];
+    WO_TEST_FALSE([NSObject WOTest_object:self isKindOfClass:NSClassFromString(@"WOLightweightRoot")]);
 }
 
 - (void)testInstancesOfClassAreKindOfClass
                 respondsToSelector:@selector(bar)]);
 
     // should handle custom root classes without problems
-    WO_TEST([NSObject WOTest_object:root respondsToSelector:@selector(dealloc)]);
+    WO_TEST([NSObject WOTest_object:root respondsToSelector:@selector(exampleMethod)]);
     WO_TEST_FALSE([NSObject WOTest_object:root respondsToSelector:@selector(foobar)]);
-
-    // cleanup
-    [root dealloc];
 }
 
 - (void)testClassRespondsToSelector
 
     // should work with custom root classes
     WO_TEST([NSObject WOTest_instancesOfClass:NSClassFromString(@"WOLightweightRoot") respondToSelector:@selector(forward::)]);
-    WO_TEST([NSObject WOTest_instancesOfClass:NSClassFromString(@"WOLightweightRoot") respondToSelector:@selector(dealloc)]);
+    WO_TEST([NSObject WOTest_instancesOfClass:NSClassFromString(@"WOLightweightRoot") respondToSelector:@selector(exampleMethod)]);
     WO_TEST_FALSE([NSObject WOTest_instancesOfClass:NSClassFromString(@"WOLightweightRoot")
                                   respondToSelector:@selector(conformsToProtocol:)]);
 }
index d53d1f6c2d91d2bba0637ef4904661b3366b7265..90a26536172654ac95abbb53da119d2e7c8b979c 100644 (file)
     // should throw if passed NULL
     mock = [WOClassMock alloc];
     WO_TEST_THROWS([mock initWithClass:NULL]);
-    [mock release];
 
     // should throw if passed non-class pointer
     mock = [WOClassMock alloc];
     WO_TEST_THROWS([mock initWithClass:(Class)self]);
-    [mock release];
 
     // otherwise should work
-    WO_TEST_DOES_NOT_THROW
-        ([[[WOClassMock alloc] initWithClass:[self class]] autorelease]);
+    WO_TEST_DOES_NOT_THROW([[WOClassMock alloc] initWithClass:[self class]]);
 
     // should throw if passed a meta class
     Class class     = [NSString class];
     Class metaclass = object_getClass(class);
     mock = [WOClassMock alloc];
     WO_TEST_THROWS([mock initWithClass:metaclass]);
-    [mock release];
 }
 
 - (void)testAccept
index 6228462cbee9ff11b498b7fbdc642369527068e9..ab472edef3b43cca56ed8ee2096e03834c919ae9 100644 (file)
 
 - (void)testInitWithObjectClass
 {
-    WOObjectMock *mock =
-        [[[WOMock alloc] initWithObjectClass:[self class]] autorelease];
+    WOObjectMock *mock = [[WOMock alloc] initWithObjectClass:[self class]];
 
     // make sure WOObjectMock class is returned
     WO_TEST_EQ([mock class], [WOObjectMock class]);
     // should throw exception instead of entering infinite loop
     mock = [WOObjectMock alloc];
     WO_TEST_THROWS([mock initWithObjectClass:[self class]]);
-    [mock release];
 }
 
 - (void)testInitWithClass
 {
-    WOClassMock *mock =
-        [[[WOMock alloc] initWithClass:[self class]] autorelease];
+    WOClassMock *mock = [[WOMock alloc] initWithClass:[self class]];
 
     // make sure WOClassMock class is returned
     WO_TEST_EQ([mock class], [WOClassMock class]);
     // cannot test this because subclass implements that method directly
     //mock = [WOClassMock alloc];
     //WO_TEST_THROWS([mock initWithClass:[self class]]);
-    //[mock release];
 }
 
 - (void)testInitWithProtocol
 {
-    WOProtocolMock *mock =
-        [[[WOMock alloc] initWithProtocol:@protocol(WOTest)] autorelease];
+    WOProtocolMock *mock = [[WOMock alloc] initWithProtocol:@protocol(WOTest)];
 
     // make sure WOProtocolMock class is returned
     WO_TEST_EQ([mock class], [WOProtocolMock class]);
     // cannot test this because subclass implements that method directly
     //mock = [WOProtocolMock alloc];
     //WO_TEST_THROWS([mock initWithProtocol:@protocol(WOTest)]);
-    //[mock release];
 }
 
 - (void)testRecordingMethods
 {
     // all recording methods should throw an exception (use subclasses instead)
-    WOMock *mock = [[[WOMock alloc] init] autorelease];
+    WOMock *mock = [[WOMock alloc] init];
     WO_TEST_THROWS([mock reject]);
     WO_TEST_THROWS([mock expectInOrder]);
     WO_TEST_THROWS([mock expectOnce]);
index c3483b722fa6df0c234386ec10c43f03a3930540..e61e3d554dda7493936d2404e23a532bcdf6aa58 100644 (file)
@@ -52,7 +52,7 @@
     id *object = NULL;                                          // cause a crash, but WOTest should keep running
     *object = @"foo";                                           // SIGBUS here
     WO_TEST_FAIL;                                               // this line never reached
-    [pool release];                                             // nor this one, but pools are in a stack no problem
+    [pool drain];                                               // nor this one, but pools are in a stack no problem
 }
 
 #pragma mark -
index f458aeb947d4c474fe2a717ce834c29e06658662..c196db7b05c9264a91a9a3f457d10437b99cbb09 100644 (file)
 
 - (void)testInitWithClass
 {
-    // preliminaries
-    WOObjectMock *mock = nil;
-
     // should throw if passed NULL
-    mock = [WOObjectMock alloc];
-    WO_TEST_THROWS([mock initWithClass:NULL]);
-    [mock release];
+    WO_TEST_THROWS([[WOObjectMock alloc] initWithClass:NULL]);
 
     // should throw if passed non-class pointer
-    mock = [WOObjectMock alloc];
-    WO_TEST_THROWS([mock initWithClass:(Class)self]);
-    [mock release];
+    WO_TEST_THROWS([[WOObjectMock alloc] initWithClass:(Class)self]);
 
     // otherwise should work
-    WO_TEST_DOES_NOT_THROW
-        ([[[WOObjectMock alloc] initWithClass:[self class]] autorelease]);
+    WO_TEST_DOES_NOT_THROW([[WOObjectMock alloc] initWithClass:[self class]]);
 
     // should throw if passed a meta class
-    Class class     = [NSString class];
-    Class metaclass = object_getClass(class);
-    mock = [WOObjectMock alloc];
-    WO_TEST_THROWS([mock initWithClass:metaclass]);
-    [mock release];
+    WO_TEST_THROWS([[WOObjectMock alloc] initWithClass:object_getClass([NSString class])]);
 }
 
 - (void)testMockExpectInOrder
     [[mock expect] lowercaseString];        // a valid NSString selector
     WO_TEST_DOES_NOT_THROW([mock lowercaseString]);
     WO_TEST_DOES_NOT_THROW([mock verify]);
-    WO_TEST_DOES_NOT_THROW([mock retain]);  // ok (inherited from NSProxy)
-    WO_TEST_DOES_NOT_THROW([mock release]); // ok (inherited from NSProxy)
     WO_TEST_THROWS([mock uppercaseString]); // fail (not explicitly expected)
 
     // should throw for class methods
 
     // should raise if passed nil class
     WO_TEST_THROWS([WOObjectMock mockForClass:nil]);
-    WO_TEST_THROWS([[[WOObjectMock alloc] initWithClass:nil] release]);
+    WO_TEST_THROWS([[WOObjectMock alloc] initWithClass:nil]);
     WO_TEST_DOES_NOT_THROW([WOObjectMock mockForClass:aClass]);
-    WO_TEST_DOES_NOT_THROW([[[WOObjectMock alloc] initWithClass:aClass] release]);
+    WO_TEST_DOES_NOT_THROW([[WOObjectMock alloc] initWithClass:aClass]);
 
     // test if passed a non-class object (ie. an instance)
 
     // raise if initialized with nil class pointer
     WO_TEST_DOES_NOT_THROW([WOObjectStub stubForClass:aClass withDelegate:nil]);
     WO_TEST_THROWS([WOObjectStub stubForClass:nil withDelegate:nil]);
-    WO_TEST_DOES_NOT_THROW([[[WOObjectStub alloc] initWithClass:aClass delegate:nil] release]);
-    WO_TEST_THROWS([[[WOObjectStub alloc] initWithClass:nil delegate:nil] release]);
+    WO_TEST_DOES_NOT_THROW([[WOObjectStub alloc] initWithClass:aClass delegate:nil]);
+    WO_TEST_THROWS([[WOObjectStub alloc] initWithClass:nil delegate:nil]);
 
     // test if passed a non-class object (ie. an instance)
 
     WO_TEST_DOES_NOT_THROW(stub = [WOObjectStub stubForClass:aClass withDelegate:nil]);
     WO_TEST_THROWS([stub recordedInvocation]);
 
-    // test automatic verify on dealloc
+    // test automatic verify on finalize
 }
 
 - (void)testStubEquality
index 30bf09156f02172a9648e76348719f1fa9b33949..d159eb944499811412cf6bfb98865a6f26de16ad 100644 (file)
@@ -35,7 +35,6 @@
     // should throw for NULL protocol
     WOProtocolMock *mock = [WOProtocolMock alloc];
     WO_TEST_THROWS([mock initWithProtocol:NULL]);
-    [mock release];
 }
 
 - (void)testMethodSignatureForSelector
index d2400ba96f2ad901dbbef6b0e02d3e51fa64ef04..a5544b1dc2a5323c3afa9ed441da721ba21fed6c 100644 (file)
     // throws if passed NULL
     WOProtocolStub *stub = [WOProtocolStub alloc];
     WO_TEST_THROWS([stub initWithProtocol:NULL delegate:nil]);
-    [stub dealloc];
 
     // otherwise works
     stub = [WOProtocolStub alloc];
     WO_TEST_DOES_NOT_THROW([stub initWithProtocol:@protocol(WOTest) delegate:nil]);
-    [stub dealloc];
 }
 
 - (void)testMethodSignatureForSelector
index 076ab513429b7a66443bc52e28bb1731a598115b..ec70ed24f1709e38ba8dbb4ab08372e9dff88083 100644 (file)
@@ -25,7 +25,7 @@
 
 - (void)testMatchesInvocation
 {
-    WOStub *stub = [[[WOStub alloc] init] autorelease];
+    WOStub *stub = [[WOStub alloc] init];
 
     // raises if sent nil
     WO_TEST_THROWS([stub matchesInvocation:nil]);
index d31cb3c4f786465c0c5d3495e7ac5aeccd035c0e..09aed92138f2b1c69050207da7d49e897e1d7976 100644 (file)
@@ -39,31 +39,19 @@ NSMutableArray *WOEmptyInstanceMethodInvocations;
 
 + (void)initialize
 {
-    WOEmptyClassMethodInvocations =
-        [[NSMutableArray alloc] initWithCapacity:3];
-    WOEmptyInstanceMethodInvocations =
-        [[NSMutableArray alloc] initWithCapacity:3];
+    WOEmptyClassMethodInvocations = [NSMutableArray arrayWithCapacity:3];
+    WOEmptyInstanceMethodInvocations = [NSMutableArray arrayWithCapacity:3];
 }
 
 + (void)verify
 {
-    // cleanup
-    [WOEmptyClassMethodInvocations autorelease];
-    [WOEmptyInstanceMethodInvocations autorelease];
-
     // were class methods called in order?
-    NSArray *expectedClassMethods = [NSArray arrayWithObjects:
-            @"preflight", @"testClassMethod", @"postflight", nil];
-    NSAssert
-        ([expectedClassMethods isEqualToArray:WOEmptyClassMethodInvocations],
-         @"Class method verification failed");
+    NSArray *expectedClassMethods = [NSArray arrayWithObjects:@"preflight", @"testClassMethod", @"postflight", nil];
+    NSAssert([expectedClassMethods isEqualToArray:WOEmptyClassMethodInvocations], @"Class method verification failed");
 
     // were instance methods called in order?
-    NSArray *expectedInstanceMethods = [NSArray arrayWithObjects:
-        @"preflight", @"testInstanceMethod", @"postflight", nil];
-    NSAssert([expectedInstanceMethods isEqualToArray:
-        WOEmptyInstanceMethodInvocations],
-             @"Instance method verification failed");
+    NSArray *expectedInstanceMethods = [NSArray arrayWithObjects:@"preflight", @"testInstanceMethod", @"postflight", nil];
+    NSAssert([expectedInstanceMethods isEqualToArray:WOEmptyInstanceMethodInvocations], @"Instance method verification failed");
 }
 
 + (void)preflight
@@ -115,11 +103,6 @@ NSMutableArray *WOEmptyInstanceMethodInvocations;
     return class_createInstance(class, 0);
 }
 
-- (void)dealloc
-{
-    free(self);
-}
-
 // http://www.geocities.com/chrootstrap/custom_objective_c_root_classes.html
 // http://darwinsource.opendarwin.org/10.3/objc4-235/runtime/Messengers.subproj/objc-msg-ppc.s
 // Apple's runtime makes the assumption that this method is implemented
@@ -1048,7 +1031,7 @@ NSMutableArray *WOEmptyInstanceMethodInvocations;
     WO_TEST_DOES_NOT_THROW([objectValue WOTest_testIsEqualToValue:nilValue]);
     WO_TEST_DOES_NOT_THROW([nilValue WOTest_testIsEqualToValue:objectValue]);
 
-    NSValue *realObjectValue = [NSValue valueWithNonretainedObject:[[[NSObject alloc] init] autorelease]];
+    NSValue *realObjectValue = [NSValue valueWithNonretainedObject:[[NSObject alloc] init]];
     WO_TEST_FALSE([realObjectValue WOTest_isObject]);
     WO_TEST_TRUE([realObjectValue WOTest_isPointerToVoid]);
     WO_TEST_DOES_NOT_THROW([realObjectValue WOTest_testIsEqualToValue:nilValue]);
@@ -1134,13 +1117,13 @@ NSMutableArray *WOEmptyInstanceMethodInvocations;
     WO_TEST_EQUAL([NSException WOTest_descriptionForException:exception1], @"foo: bar");
 
     // NSImage responds to name but not reason
-    NSImage *exception2 = [[[NSImage alloc] initWithSize:NSZeroSize] autorelease];
+    NSImage *exception2 = [[NSImage alloc] initWithSize:NSZeroSize];
     [exception2 setName:@"Roger Smith"];
     WO_TEST_EQUAL([NSException WOTest_descriptionForException:exception2],
                   ([NSString stringWithFormat:@"%@ (%x)", [exception2 name], exception2]));
 
     // NSObject responds to description but not to name or reason
-    NSObject *exception3 = [[[NSObject alloc] init] autorelease];
+    NSObject *exception3 = [[NSObject alloc] init];
     WO_TEST_EQUAL([NSException WOTest_descriptionForException:exception3], [exception3 description]);
 
     WO_TEST_EQUAL([NSException WOTest_nameForException:nil], @"no exception");
@@ -1891,16 +1874,12 @@ NSMutableArray *WOEmptyInstanceMethodInvocations;
 
 - (void)throwWORootClassObject
 {
-    WORootClass *object = [WORootClass new]; // this is officially a leak
-    @throw object;
-    [object dealloc]; // leaks because this line is never reached
+    @throw [WORootClass new];
 }
 
 - (void)throwObject
 {
-    Object *object = [[Object alloc] init]; // another leak
-    @throw object;
-    [object free]; // leaks because this line is never reached
+    @throw [[Object alloc] init];
 }
 
 - (void)doNotThrowException
@@ -1911,7 +1890,7 @@ NSMutableArray *WOEmptyInstanceMethodInvocations;
 - (void)makeCocoaThrowException
 {
     // should throw NSInvalidArgumentException
-    (void)[[[NSString alloc] initWithFormat:nil] autorelease];
+    (void)[[NSString alloc] initWithFormat:nil];
 }
 
 - (void)makeCocoaThrowNSRangeException
index 64b4d12eac7a42fdaf4816e5a2c385288796210a..aa75af9735bd062f60d047757ef9d476c8cbe831 100644 (file)
@@ -31,8 +31,6 @@
 
 + (id)newLightweightRoot;
 
-- (void)dealloc;
-
 /*! This method required by the runtime (called by _objc_forward for unrecognized selectors). The default implementation simply raises an NSInternalInconsistencyException. */
 - forward:(SEL)sel :(marg_list)args;
 
index 6f8a0ea7a5edec0f0eac8f5e25ac3ba192896aed..a29c79961da3699e0d7f9e430b1805590da8b651 100644 (file)
@@ -38,9 +38,9 @@
     return class_createInstance(class, 0);
 }
 
-- (void)dealloc
+- (void)exampleMethod
 {
-    free(self);
+    // do nothing
 }
 
 - forward:(SEL)sel :(marg_list)args
index de270c862d4b92ad3033371d68878f48b81bc1ba..15f8e5d7a1e7506627fec1c3e421224e7f505a97 100644 (file)
--- a/WOMock.h
+++ b/WOMock.h
@@ -102,7 +102,7 @@ The mocked class must at least implement the NSObject method, instanceMethodSign
 
  Rejected selectors cause an exception to be raised.
 
- By default, if a selector does not appear in any of the internal lists an exception is raised. This latter behaviour requires you to be explicit about <em>all</em> selectors which a mock object may receive. For example, you may have a mock object that stands in for an NSString instance and expect that it be sent a "lowercaseString" selector. If during your test you also send an "uppercaseString" selector then an exception will be raised (because the selector does not appear in the internal lists, even though it is a valid NSString selector). A small number of methods will be accepted even without being explicitly added the the lists; these include methods like retain and release and other NSObject protocol methods. These are accepted because they are inherited from the parent class of WOMock (NSProxy).
+ By default, if a selector does not appear in any of the internal lists an exception is raised. This latter behaviour requires you to be explicit about <em>all</em> selectors which a mock object may receive. For example, you may have a mock object that stands in for an NSString instance and expect that it be sent a "lowercaseString" selector. If during your test you also send an "uppercaseString" selector then an exception will be raised (because the selector does not appear in the internal lists, even though it is a valid NSString selector). A small number of methods will be accepted even without being explicitly added the the lists; these include methods such as NSObject protocol methods. These are accepted because they are inherited from the parent class of WOMock (NSProxy).
 
  If you wish to override this behaviour you may send the setAcceptsByDefault message passing a flag of YES, but be aware that selectors which fall through to the "accepts by default" cannot return any defined value. For control over return values the selector in question must be explicitly set up with the expectInOrder, expectOnce, expect, acceptOnce or accept methods.
 
@@ -144,7 +144,7 @@ See the WOMockTests class in WOTestSelfTests for usage examples.
  */
 - (id)reject;
 
-/*! Instructs the receiver to expect a selector; the receiver not only accepts the selector but it actually requires that it be sent. If the expected selector has not been received when the verify method is called (or at dealloc time) then an exception will be raised. The following example shows how to instruct the WOMock instance mock to expect the disconnect selector:
+/*! Instructs the receiver to expect a selector; the receiver not only accepts the selector but it actually requires that it be sent. If the expected selector has not been received when the verify method is called (or at finalize time) then an exception will be raised. The following example shows how to instruct the WOMock instance mock to expect the disconnect selector:
 
 \code
 [[mock expect] disconnect];
@@ -176,7 +176,7 @@ If the selector takes arguments then the arguments passed to the mock must match
 
 /*! \endgroup */
 
-/*! Verifies that all selectors registered with the expect method have been performed. If any have not then an exception is raised. The verify method is automatically called at dealloc time, although you may still wish to invoke it manually. */
+/*! Verifies that all selectors registered with the expect method have been performed. If any have not then an exception is raised. The verify method is automatically called at finalize time, although you may still wish to invoke it manually. */
 - (void)verify;
 
 #pragma mark -
index 20704c003732ee7251e2c99a1223a1727f942d7d..e4ddae70425293e0f2989660c61fa254a609a571 100644 (file)
--- a/WOMock.m
+++ b/WOMock.m
     if ([self class] != [WOMock class])
         [NSException raise:NSInternalInconsistencyException format:@"initWithObjectClass: called from WOMock subclass"];
 
-    id subclass = [[WOObjectMock allocWithZone:[self zone]] initWithClass:aClass];
-
-    [self dealloc];
-    return subclass;
+    return [[WOObjectMock allocWithZone:[self zone]] initWithClass:aClass];
 }
 
 // a true Apple-style cluster would do this by allocating a placeholder object
@@ -87,9 +84,7 @@
     if ([self class] != [WOMock class])
         [NSException raise:NSInternalInconsistencyException format:@"initWithClass: called from WOMock subclass"];
 
-    id subclass = [[WOClassMock allocWithZone:[self zone]] initWithClass:aClass];
-    [self dealloc];
-    return subclass;
+    return [[WOClassMock allocWithZone:[self zone]] initWithClass:aClass];
 }
 
 // a true Apple-style cluster would do this by allocating a placeholder object
     if ([self class] != [WOMock class])
         [NSException raise:NSInternalInconsistencyException format:@"initWithProtocol: called from WOMock subclass"];
 
-    id subclass = [[WOProtocolMock allocWithZone:[self zone]] initWithProtocol:aProtocol];
-    [self dealloc];
-    return subclass;
+    return [[WOProtocolMock allocWithZone:[self zone]] initWithProtocol:aProtocol];
 }
 
 - (id)init
 {
     // super (NSProxy) has no init method
-    expectedInOrder     = [[NSMutableArray alloc] init];    // there are no accessors (to avoid namespace pollution)
-    accepted            = [[NSMutableSet alloc] init];
-    acceptedOnce        = [[NSMutableSet alloc] init];
-    expected            = [[NSMutableSet alloc] init];
-    expectedOnce        = [[NSMutableSet alloc] init];
-    rejected            = [[NSMutableSet alloc] init];
-    methodSignatures    = [[NSMutableDictionary alloc] init];
+    expectedInOrder     = [NSMutableArray array];               // there are no accessors (to avoid namespace pollution)
+    accepted            = [NSMutableSet set];
+    acceptedOnce        = [NSMutableSet set];
+    expected            = [NSMutableSet set];
+    expectedOnce        = [NSMutableSet set];
+    rejected            = [NSMutableSet set];
+    methodSignatures    = [NSMutableDictionary dictionary];
     return self;
 }
 
-- (void)dealloc
+// TODO: given that the time at which finalize is called is indeterminate consider coming up with some other mechanism for
+// triggering verification
+- (void)finalize
 {
-    [self               verify];
-    [accepted           release];
-    [acceptedOnce       release];
-    [expected           release];
-    [expectedOnce       release];
-    [expectedInOrder    release];
-    [rejected           release];
-    [methodSignatures   release];
-    [super dealloc];
+    [self verify];
 }
 
 - (id)accept
index 5dc4c27859c4ad6b3ed6bb8455550dac7e13ff76..f78ae43385a6435a309fc78cda05319ca590cac4 100644 (file)
@@ -36,7 +36,7 @@
 {
     NSParameterAssert(aClass != NULL);
     NSParameterAssert([NSObject WOTest_isRegisteredClass:aClass]);     // only registered classes pass (do not pass meta classes)
-    return [[[self alloc] initWithClass:aClass] autorelease];
+    return [[self alloc] initWithClass:aClass];
 }
 
 - (id)initWithClass:(Class)aClass
index 2dfb11ab69f71610bab1ec4e0d44e3ae028ae0e9..f0cf06f97742e84d6ee370b53e6a338a14fd0f72 100644 (file)
@@ -35,7 +35,7 @@
 + (id)stubForClass:(Class)aClass withDelegate:(id)aDelegate
 {
     NSParameterAssert(aClass != NULL);
-    return [[[self alloc] initWithClass:aClass delegate:aDelegate] autorelease];
+    return [[self alloc] initWithClass:aClass delegate:aDelegate];
 }
 
 - (id)initWithClass:(Class)aClass delegate:(id)aDelegate
index 55a5ef275517a15eb1bb2426fd5ed44965ccaa17..c7429254203a959434c137e23abebf5a82b8ef3e 100644 (file)
@@ -48,7 +48,7 @@ NSString *WOStringFromProtocol(Protocol *aProtocol)
 + (id)mockForProtocol:(Protocol *)aProtocol
 {
     NSParameterAssert(aProtocol != NULL);
-    return [[[self alloc] initWithProtocol:aProtocol] autorelease];
+    return [[self alloc] initWithProtocol:aProtocol];
 }
 
 - (id)initWithProtocol:(Protocol *)aProtocol
index f01cf20cb4f6e27c0856caba775e805db82c0dc5..59a388d65e6472fca87392c4e803a4a3fff0ed76 100644 (file)
@@ -42,7 +42,7 @@
 + (id)stubForProtocol:(Protocol *)aProtocol withDelegate:(id)aDelegate
 {
     NSParameterAssert(aProtocol != NULL);
-    return [[[self alloc] initWithProtocol:aProtocol delegate:aDelegate] autorelease];
+    return [[self alloc] initWithProtocol:aProtocol delegate:aDelegate];
 }
 
 /*! Designated initializer. */
index 188fe49e433021b31ea62f522e3675ed4a3a560d..bb5c643a0aa9cf042d6dc2713fa07125548f2733 100644 (file)
--- a/WOStub.h
+++ b/WOStub.h
@@ -48,7 +48,7 @@
 /*! Used to specify the return value that should be sent in response to messages. */
 - (id)returning:(NSValue *)aValue;
 
-/*! Used to specify the exception that should be raised in response to messages. \p anException should respond to the retain, release, autorelease, isEqual and hash selectors. */
+/*! Used to specify the exception that should be raised in response to messages. \p anException should respond to the isEqual and hash selectors. */
 - (id)raising:(id)anException;
 
 #pragma mark -
 #pragma mark -
 #pragma mark Accessors
 
-- (BOOL)acceptsAnyArguments;
-- (void)setAcceptsAnyArguments:(BOOL)flag;
-
 /*! Returns the recorded invocation object stored by this instance. Raises an exception if no invocation has yet been recorded. */
 - (NSInvocation *)recordedInvocation;
 
-/*! Direct access to the invocation instance variable. Should not be used. Use recordedInvocation instead. */
-- (NSInvocation *)invocation;
-- (void)setInvocation:(NSInvocation *)anInvocation;
-
-- (NSValue *)returnValue;
-- (void)setReturnValue:(NSValue *)aReturnValue;
+#pragma mark -
+#pragma mark Properties
 
-- (id)exception;
-- (void)setException:(id)anException;
+@property(assign) NSInvocation *invocation;
+@property(assign) NSValue *returnValue;
+@property BOOL acceptsAnyArguments;
+@property(assign) id exception;
 
 @end
index 5c6cba109582d6d0e993f2dd879037cada5eb58a..197342d725b9090709c637d7de271acb3cc55c27 100644 (file)
--- a/WOStub.m
+++ b/WOStub.m
     return self; // super (NSProxy) has no init method
 }
 
-- (void)dealloc
-{
-    [self setInvocation:nil];
-    [self setReturnValue:nil];
-    [self setException:nil];
-    [super dealloc];
-}
-
 - (id)anyArguments
 {
     [self setAcceptsAnyArguments:YES];
     return recordedInvocation;
 }
 
-- (NSInvocation *)invocation
-{
-    return [[invocation retain] autorelease];
-}
-
-- (void)setInvocation:(NSInvocation *)anInvocation
-{
-    if (invocation != anInvocation)
-    {
-        [anInvocation retain];
-        [invocation release];
-        invocation = anInvocation;
-    }
-}
-
-- (NSValue *)returnValue
-{
-    return [[returnValue retain] autorelease];
-}
-
-- (void)setReturnValue:(NSValue *)aReturnValue
-{
-    if (returnValue != aReturnValue)
-    {
-        [aReturnValue retain];
-        [returnValue release];
-        returnValue = aReturnValue;
-    }
-}
-
-- (BOOL)acceptsAnyArguments
-{
-    return acceptsAnyArguments;
-}
-
-- (void)setAcceptsAnyArguments:(BOOL)flag
-{
-    acceptsAnyArguments = flag;
-}
-
-- (id)exception
-{
-    return [[exception retain] autorelease];
-}
-
-- (void)setException:(id)anException
-{
-    if (exception != anException)
-    {
-        [anException retain];
-        [exception release];
-        exception = anException;
-    }
-}
+@synthesize invocation;
+@synthesize returnValue;
+@synthesize acceptsAnyArguments;
+@synthesize exception;
 
 @end
index 8ff81f2ffba090dc5701777cb922227215f1dc2d..2353aad7679ecbc4e500371602e39e82c07371ef 100644 (file)
--- a/WOTest.h
+++ b/WOTest.h
@@ -25,7 +25,7 @@
 #pragma mark Marker protocol
 
 
-/*! You can indicate that a class contains unit tests by marking it with the WOTest marker protocol. Although there are no selectors explicitly defined in the protocol you should at the very least ensure that your class responds to the alloc, init and release selectors (this is because before running each test method the framework instantiates a new copy of your test class by sending the alloc and init messages and afterwards sends a release message. In practice this means that any subclass of NSObject is suitable for writing test classes. You can also use classes which do not derive from the NSObject root class but you should be aware that if they do not implement alloc, init and release then WOTest will issue warnings at runtime. */
+/*! You can indicate that a class contains unit tests by marking it with the WOTest marker protocol. Although there are no selectors explicitly defined in the protocol you should at the very least ensure that your class responds to the alloc and init selectors (this is because before running each test method the framework instantiates a new copy of your test class by sending the alloc and init messages. In practice this means that any subclass of NSObject is suitable for writing test classes. You can also use classes which do not derive from the NSObject root class but you should be aware that if they do not implement alloc and init then WOTest will issue warnings at runtime. */
 @protocol WOTest
 
 @end
index e4b636608cc6317609225ed49fb2c1b31c4aa1bc..74a7950a047b222c9e40a7ecb957dced978d1222 100644 (file)
@@ -37,8 +37,8 @@
     if (OSAtomicIncrement32Barrier(&initialized) != 1) return;  // do this once only
 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    (void)[[self alloc] initWithPath:__FILE__ keepComponents:3]; // will release self after running tests
-    [pool release];
+    (void)[[self alloc] initWithPath:__FILE__ keepComponents:3];
+    [pool drain];
 }
 
 @end
@@ -83,7 +83,6 @@ extern NSString *NSApplicationDidFinishLaunchingNotification;
     [tester runAllTests];
 
     [[NSNotificationCenter defaultCenter] removeObserver:self];
-    [self release];                                 // balance alloc/init in load method
 }
 
 - (void)applicationFailedToFinishLaunching:(id)ignored
index 9f45db5bae5603df3a33cd1c9cb75336010805b3..6d12ea78640bbe9dad6b67ee19465a9caa5d87bc 100644 (file)
@@ -62,7 +62,7 @@
                 NSLog(@"WOTestBundleInjector: failed to load bundle \"%@\"", bundlePath);
         }
     }
-    [pool release];
+    [pool drain];
 }
 
 @end
index 8f21e2e35847c2c83549eac663e1c0cc4e85498d..9146ff0a6f80f9ed55a8fa8b257a2a3f9db2a880 100644 (file)
@@ -242,32 +242,6 @@ OSStatus WOLowLevelExceptionHandler(ExceptionInformation *theException)
     return instance;
 }
 
-- (oneway void)release
-{
-    return;
-}
-
-- (void)dealloc
-{
-    [self doesNotRecognizeSelector:_cmd];   // being a singleton, officially does not support dealloc
-    [super dealloc];                        // this line necessary to suppress compiler warning
-}
-
-- (unsigned)retainCount
-{
-    return UINT_MAX;
-}
-
-- (id)autorelease
-{
-    return self;
-}
-
-- (id)retain
-{
-    return self;
-}
-
 // overriding this also overrides copy
 - (id)copyWithZone:(NSZone *)zone
 {
@@ -359,7 +333,7 @@ OSStatus WOLowLevelExceptionHandler(ExceptionInformation *theException)
     for (NSString *class in [self testableClasses])
         [self runTestsForClassName:class] ? : failures++;
     [self printTestResultsSummary];
-    [pool release];
+    [pool drain];
     return (failures > 0) ? NO : YES;
 }
 
@@ -440,10 +414,9 @@ jump_point:
                     }
                     else if ([self isInstanceMethod:method])
                     {
-                        // class must implement alloc, init and release
+                        // class must implement alloc and init
                         if ([NSObject WOTest_object:aClass respondsToSelector:@selector(alloc)] &&
-                            [NSObject WOTest_instancesOfClass:aClass respondToSelector:@selector(init)] &&
-                            [NSObject WOTest_instancesOfClass:aClass respondToSelector:@selector(release)])
+                            [NSObject WOTest_instancesOfClass:aClass respondToSelector:@selector(init)])
                         {
                             id instance = [[aClass alloc] init];
                             if ([NSObject WOTest_instancesOfClass:aClass respondToSelector:preflight])
@@ -451,11 +424,10 @@ jump_point:
                             objc_msgSend(instance, [self selectorFromMethod:method]);
                             if ([NSObject WOTest_instancesOfClass:aClass respondToSelector:postflight])
                                 objc_msgSend(instance, postflight);
-                            [instance release];
                         }
                         else
                         {
-                            [self writeError:@"Class %@ must respond to the alloc, init and release selectors",
+                            [self writeError:@"Class %@ must respond to the alloc and init selectors",
                                 NSStringFromClass(aClass)];
                             [self writeLastKnownLocation];
                         }
@@ -491,7 +463,7 @@ jump_point:
                     if (lowLevelExceptionHandlerInstalled)
                         [self removeLowLevelExceptionHandler];
                     _WOLog(@"Finished test method %@ (%.4f seconds)", method, -[startMethod timeIntervalSinceNow]);
-                    [pool release];
+                    [pool drain];
                 }
             }
         }
@@ -630,8 +602,7 @@ jump_point:
         }
     }
 
-    // return autoreleased, immutable NSArray
-    return [NSArray arrayWithArray:classNames];
+    return [classNames copy];   // return immutable
 }
 
 - (NSArray *)testableMethodsFrom:(Class)aClass
@@ -763,7 +734,7 @@ jump_point:
     [environment removeObjectForKey:@"DYLD_INSERT_LIBRARIES"];
     [environment removeObjectForKey:@"WOTestBundleInjector"];
 
-    NSTask *task = [[[NSTask alloc] init] autorelease];
+    NSTask *task = [[NSTask alloc] init];
     [task setLaunchPath:@"/usr/bin/env"];   // use env so as to pick up PATH, if set
     [task setEnvironment:environment];
     NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"growlnotify",
index 6e01b6111467a06e9cb414ff26712292a4d89fb0..694b1d8a78153cdd113135d76d265dd8e8065d73 100644 (file)
@@ -33,7 +33,7 @@
     NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
         [NSNumber numberWithInt:kind], WOTestLowLevelExceptionKind, nil];
 
-    return [[[self alloc] initWithName:WOTestLowLevelExceptionName reason:reason userInfo:userInfo] autorelease];
+    return [[self alloc] initWithName:WOTestLowLevelExceptionName reason:reason userInfo:userInfo];
 }
 
 + (NSString *)nameForType:(ExceptionKind)kind
index 16ad17f5c85af8bb54c16f385fc4401887d33e46..6c1d730bf2bccdef62f0a78f21627538ea1ebe32 100644 (file)
@@ -171,7 +171,7 @@ int main(int argc, const char *argv[])
         exitCode = EXIT_FAILURE;
 
 cleanup:
-    [pool release];
+    [pool drain];
     return exitCode;
 }