diff --git a/ChangeLog b/ChangeLog index 4a3e391ae..9fa02b009 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2003-06-15 Richard Frith-Macdonald + + * Source/NSAutoreleasePool.m: Documented. + * Headers/gnustep/base/NSObject.h: Documented memory management macros + for autogsdoc. + 2003-06-14 Richard Frith-Macdonald * Source/Additions/GSMime.m: Better attempt to infer charset from diff --git a/Headers/gnustep/base/NSObject.h b/Headers/gnustep/base/NSObject.h index 8238f0472..d725ee852 100644 --- a/Headers/gnustep/base/NSObject.h +++ b/Headers/gnustep/base/NSObject.h @@ -374,41 +374,57 @@ GS_EXPORT NSRecursiveLock *gnustep_global_lock; #else -/* - * Basic retain, release, and autorelease operations. - */ #ifndef RETAIN +/** + * Basic retain operation ... calls [NSObject-retain] + */ #define RETAIN(object) [object retain] #endif + #ifndef RELEASE +/** + * Basic release operation ... calls [NSObject-release] + */ #define RELEASE(object) [object release] #endif + #ifndef AUTORELEASE +/** + * Basic autorelease operation ... calls [NSObject-autorelease] + */ #define AUTORELEASE(object) [object autorelease] #endif -/* - * Tested retain, release, and autorelease operations - only invoke the +#ifndef TEST_RETAIN +/** + * Tested retain - only invoke the * objective-c method if the receiver is not nil. */ -#ifndef TEST_RETAIN #define TEST_RETAIN(object) ({\ id __object = (id)(object); (__object != nil) ? [__object retain] : nil; }) #endif #ifndef TEST_RELEASE +/** + * Tested release - only invoke the + * objective-c method if the receiver is not nil. + */ #define TEST_RELEASE(object) ({\ id __object = (id)(object); if (__object != nil) [__object release]; }) #endif #ifndef TEST_AUTORELEASE +/** + * Tested autorelease - only invoke the + * objective-c method if the receiver is not nil. + */ #define TEST_AUTORELEASE(object) ({\ id __object = (id)(object); (__object != nil) ? [__object autorelease] : nil; }) #endif -/* +#ifndef ASSIGN +/** * ASSIGN(object,value) assigns the value to the object with * appropriate retain and release operations. */ -#ifndef ASSIGN #define ASSIGN(object,value) ({\ id __value = (id)(value); \ id __object = (id)(object); \ @@ -427,11 +443,11 @@ if (__value != __object) \ }) #endif -/* +#ifndef ASSIGNCOPY +/** * ASSIGNCOPY(object,value) assigns a copy of the value to the object * with release of the original. */ -#ifndef ASSIGNCOPY #define ASSIGNCOPY(object,value) ({\ id __value = (id)(value); \ id __object = (id)(object); \ @@ -450,14 +466,14 @@ if (__value != __object) \ }) #endif -/* +#ifndef DESTROY +/** * DESTROY() is a release operation which also sets the variable to be * a nil pointer for tidyness - we can't accidentally use a DESTROYED * object later. It also makes sure to set the variable to nil before * releasing the object - to avoid side-effects of the release trying * to reference the object being released through the variable. */ -#ifndef DESTROY #define DESTROY(object) ({ \ if (object) \ { \ @@ -469,16 +485,19 @@ if (__value != __object) \ #endif #ifndef CREATE_AUTORELEASE_POOL +/** + * Declares an autorelease pool variable and creates and initialises + * an autorelease pool object. + */ #define CREATE_AUTORELEASE_POOL(X) \ NSAutoreleasePool *(X) = [NSAutoreleasePool new] #endif -/* +#ifndef RECREATE_AUTORELEASE_POOL +/** * Similar, but allows reuse of variables. Be sure to use DESTROY() * so the object variable stays nil. */ - -#ifndef RECREATE_AUTORELEASE_POOL #define RECREATE_AUTORELEASE_POOL(X) \ if (X == nil) \ (X) = [NSAutoreleasePool new] diff --git a/Source/NSAutoreleasePool.m b/Source/NSAutoreleasePool.m index 6f7da5366..9afba2a5e 100644 --- a/Source/NSAutoreleasePool.m +++ b/Source/NSAutoreleasePool.m @@ -2,6 +2,7 @@ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by: Andrew Kachites McCallum + Written by: Richard Frith-Macdonald Date: January 1995 This file is part of the GNUstep Base Library. @@ -121,8 +122,28 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv) /** *

- * This class maintains a stack of autorelease pools objects - * in each thread. + * The standard OpenStep system of memory management employs retain counts. + * When an object is created, it has a retain count of 1. When an object + * is retained, the retain count is incremented. When it is released the + * retain count is decremented, and when the retain count goes to zero the + * object gets deallocated. + *

+ *

+ * A simple retain/release mechanism is not very interesting ... + * so it's spiced up with autorelease pools. You can use the + * AUTORELEASE() macro to call the [NSObject-autorelease] + * method, which adds an object to the current autorelease pool by + * calling [NSAutoreleasePool+addObject:].
+ * An autorelease pool simply maintains a reference to each object + * added to it, and for each addition, the autorelease pool will + * call the [NSObject-release] method of the object when the pool + * is released. So doing an AUTORELEASE() is just the same as + * doing a RELEASE(), but deferred until the current autorelease + * pool is deallocated. + *

+ *

+ * The NSAutoreleasePool class maintains a separate stack of + * autorelease pools objects in each thread. *

*

* When an autorelease pool is created, it is automatically @@ -132,6 +153,50 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv) * When a pool is destroyed, it (and any pool later in * the stack) is removed from the stack. *

+ *

+ * This mechanism provides a simple but controllable and reasonably + * efficient way of managing temporary objects. An object can be + * autoreleased and then passed around and used until the topmost + * pool in the stack is destroyed. + *

+ *

+ * Most methods return objects which are either owned by autorelease + * pools or by the receiver of the method, so the lifetime of the + * returned object can be assumed to be the shorter of the lifetime + * of the current autorelease pool, or that of the receiver on which + * the method was called.
+ * The exceptions to this are those object returned by - + *

+ * + * [NSObject+alloc], [NSObject+allocWithZone:] + * + * Methods whose names begin with alloc return an uninitialised + * object, owned by the caller. + * + * [NSObject-init] + * + * Methods whose names begin with init return an initialised + * version of the receiving object, owned by the caller.
+ * NB. The returned object may not actualy be the same as the + * receiver ... sometimes an init method releases the original + * receiver and returns an alternative. + *
+ * [NSObject+new] + * + * Methods whose names begin with new combine the effects of + * allocation and initialisation. + * + * [NSObject-copy], [(NSCopying)-copyWithZone:] + * + * Methods whose names begin with copy create a copy of the receiver + * which is owned by the caller. + * + * [NSObject-mutableCopy], [(NSMutableCopying)-mutableCopyWithZone:] + * + * Methods whose names begin with mutableCopy create a copy of the receiver + * which is owned by the caller. + * + *
*/ @implementation NSAutoreleasePool @@ -293,7 +358,7 @@ static IMP initImp; /** * Adds the specified object to the current autorelease pool. * If there is no autorelease pool in the thread, - * a warning is logged. + * a warning is logged and the object is leaked (ie it will not be released). */ + (void) addObject: (id)anObj { @@ -494,11 +559,20 @@ static IMP initImp; free_pool_cache(tv); } +/** + * Resets (to zero) the count of autoreleased objects in the current thread. + */ + (void) resetTotalAutoreleasedObjects { ARP_THREAD_VARS->total_objects_count = 0; } +/** + * Returns the number of objects which have been autoreleased in the + * current thread since the last call to +resetTotalAutoreleasedObjects.
+ * NB. This is not normally supported ... enable it as a compile time option + * by editing NSAutoreleasePool.m when building the base library. + */ + (unsigned) totalAutoreleasedObjects { return ARP_THREAD_VARS->total_objects_count; @@ -554,3 +628,4 @@ static IMP initImp; } @end +