ftp.nice.ch/peanuts/GeneralData/Documents/openstep/OpenStepSpec_rtf.tar.gz#/OpenStepSpec_rtf/FoundationKit/Classes/NSAutoreleasePool.rtf

This is NSAutoreleasePool.rtf in view mode; [Download] [Up]

paperh18648 margl-907 margr0 margt0 margb0 fi0 ri0 ql sb0 f1 fs24 Copyright f3 'e3f1 1994 by NeXT Computer, Inc.  All Rights Reserved.

s4 li100 fi0 ri1007 ql f0 b fs36 fs100 
fs36 NSAutoreleasePool 
pard s11 li2872 fi-2771 ri1007 ql tx2872 f1 b0 fs28 fs48 
fs28 f0 b fs24 Inherits From:tab b0 fs28 f1 NSObject
fs20 
fs28 s6 f0 b fs24 Conforms To:tab b0 fs28 f1 NSObject (NSObject)
fs20 
fs28 s7 f0 b fs24 Declared In:tab b0 fs28 f1 Foundation/NSAutoreleasePool.h 
fs20 
fs28 pard s16 li100 fi0 ri1007 ql f0 b fs28 fs20 
fs28 Class Description
fs14 
fs28 pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 b0 fs2 
fs28 The Foundation Kit uses the NSAutoreleasePool class to implement NSObject'27s b autoreleaseb0  method. An autorelease pool simply contains other objects, and when deallocated, sends a b releaseb0  message to each of those objects. An object can be put into the same pool several times, and receives a b releaseb0  message for each time it was put into the pool. 
fs16 
fs28 You use autorelease pools to limit the time an object remains valid after it'27s been 'aaautoreleased'ba (that is, after it'27s been sent an b autoreleaseb0  message or has otherwise been added to an autorelease pool). Autorelease pools are created using the usual b allocb0  and b initb0  messages, and disposed of with b releaseb0 . An autorelease pool should always be released in the same context (invocation of a method or function, or body of a loop) that it was created. You should never send b retainb0  or b autoreleaseb0  messages to an autorelease pool.
fs16 
fs28 Autorelease pools are automatically created and destroyed in OpenStep applications, so your code normally doesn'27t have to worry about them. There are two cases, though, where you should explicitly create and destroy your own autorelease pools. If you'27re writing a program that'27s not based on the Application Kit, such as a UNIX tool, there'27s no built-in support for autorelease pools; you must create and destroy them yourself. Also, if you need to write a loop that creates many temporary objects, you should create an autorelease pool in the loop to prevent too long a delay in the disposal of those objects.
fs16 
fs28 Enabling the autorelease feature in a program that'27s not based on the Application Kit is easy. Many programs have a top-level loop where they do most of their work. To enable the autorelease feature you create an autorelease pool at the beginning of this loop and release it at the end. An b autoreleaseb0  message sent in the body of the loop automatically puts its receiver into this pool. The b main()b0  function might look like this:
fs16 
fs28 pard s5 li1231 fi0 ri1007 ql f2 fs20 int main(int argc, char *argv[])
fi0 {
fi0     int i;
fi0 
    /* Do whatever setup is needed. */
    for (i = 0; i < argc; i++) {
fi0         NSAutoreleasePool *pool;
fi0         NSString *fileContents;
fi0 
fi0         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
fi0         fileContents = [[[NSString alloc] initWithContentsOfFile:argv[i]] autorelease];
fi0         processFile(fileContents);
fi0         [pool release];
fi0     }
fi0 
    /* Do whatever cleanup is needed. */
fi0     exit(EXIT_SUCCESS);
fi0 }
pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 fs28 fs16 
fs28 Any object autoreleased inside the b forb0  loop, such as the b fileContentsb0  string object, is added to b poolb0 , and when b poolb0  is released at the end of the loop those objects are also released.
fs16 
fs28 Note that autoreleasing doesn'27t work outside of the loop. This isn'27t a problem, since the program terminates shortly after the loop ends, and memory leaks aren'27t usually serious at that stage of execution. Your cleanup code shouldn'27t refer to any objects created inside the loop, though, since they may be autoreleased in the loop and therefore released as soon as it ends.
fs16 
fs28 pard s15 li477 fi0 ri1007 ql f0 b fs24 fs4 
fs24 Nesting Autorelease Pools
pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 b0 fs28 fs16 
fs28 You may need to manually create and destroy autorelease pools even in an application that uses the Application Kit if you write loops that create many temporary objects. For example, if you write a loop that iterates 1000 times and invokes a method that creates 15 temporary objects, those 15,000 objects will remain until the application'27s autorelease pool is deallocated, possibly well after they'27re no longer needed.
fs16 
fs28 You can create your own autorelease pools within the loop to prevent these unwanted objects from remaining around. Autorelease pools nest themselves on a per-thread basis, so that if you create your own pool, it adds itself to the application'27s default pool, forming a stack of autorelease pools. Likewise, if you create another pool (within a nested loop, perhaps), it adds itself to the first pool you created. b autoreleaseb0  automatically adds its receiver to the last pool created, creating a nesting of autorelease contexts. The implications of this are described below.
fs16 
fs28 A method that creates autorelease pools looks much like the b main()b0  function given above:
fs16 
fs28 pard s5 li1231 fi0 ri1007 ql f2 fs20 - (void)processString:(NSString *)aString
fi0 {
fi0     int i;
fi0 
    for (i = 0; i < 1000; i++) {
fi0         NSAutoreleasePool *subpool = [[NSAutoreleasePool alloc] init];
fi0         NSString *thisLine;
fi0 
fi0         thisLine = [self lineNumbered:i fromString:aString];
fi0         /* Do some work with thisLine. */
fi0         [subpool release];
fi0     }
fi0     return;
fi0 }
pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 fs28 fs16 
fs28 If you assume that b lineNumbered:fromString:b0  returns a string object that'27s been autoreleased while b subpoolb0  is in effect, that object is released with b subpoolb0  at the end of the loop. The work involving b thisLineb0  may create other temporary objects, which are also released at the end of the loop. None of these objects remains outside of this loop or the b processString:b0  method (unless they'27ve been retained).
fs16 
fs28 Note that because an autorelease pool adds itself to the previous pool when created, it doesn'27t cause a memory leak in the face of an exception or other sudden transfer out of the current context. If an exception occurs in the above loop, or if the work in the loop involves immediately returning or breaking out of the loop, the sub-pool is released by the application'27s default pool (or whatever pool was in effect before the sub-pool was created), 'aaunwinding'ba the autorelease-pool stack up to the one that'27s supposed to be active.
fs16 
fs28 pard s15 li477 fi0 ri1007 ql f0 b fs24 fs4 
fs24 Guaranteeing the Foundation Ownership Policy
pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 b0 fs28 fs16 
fs28 By manually creating an autorelease pool, you reduce the potential lifetime of temporary objects to the lifetime of that pool. After an autorelease pool is deallocated, you should regard as 'aadisposed of'ba any object that was autoreleased while that pool was in effect, and not send a message to that object or return it to the invoker of your method. This method, for example, is incorrect:
fs16 
fs28 pard s5 li1231 fi0 ri1007 ql f2 fs20 {f3 -} findMatchingObject:anObject
fi0 {
fi0     id match = nil;
fi0     while (match == nil) {
fi0         NSAutoreleasePool *subpool = [[NSAutoreleasePool alloc] init];
fi0 
fi0        /* Do some searching that creates a lot of temporary objects.*/
fi0 
fi0         match = [self expensiveSearchForObject:anObject];
fi0         [subpool release];
fi0     }
fi0     /* Danger!! The match object may not exist at this point! */
    [match setIsMatch:YES forObject:anObject];
fi0     return match;
fi0 }
pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 fs28 fs16 
fs28 b expensiveSearchForObject:b0  is invoked while b subpoolb0  is in effect, which means that b matchb0 , which may have been autoreleased, is released at the bottom of the loop. Sending b setIsMatch:forObject:b0  after the loop could cause the application to crash. Similarly, returning b matchb0  allows the sender of b findMatchingObject:b0  to send a message to it, also causing your application to crash.
fs16 
fs28 If you must pull a temporary object out of a nested autorelease context, you can do so by retaining the object within the context and then autoreleasing it after the pool has been released. Here'27s a correct implementation of b findMatchingObject:b0 :
fs16 
fs28 pard s5 li1231 fi0 ri1007 ql f2 fs20 {f3 -} findMatchingObject:anObject
fi0 {
fi0     id match = nil;
fi0     while (match == nil) {
fi0         NSAutoreleasePool *subpool = [[NSAutoreleasePool alloc] init];
fi0     
fi0 tab tab 
fi0 
        /* Do a search that creates a lot of temporary objects. */

fi0         match = [self expensiveSearchForObject:anObject];
fi0         if (match != nil) [match retain]; /* Keep match around. */
fi0         [subpool release];
fi0     }
fi0     [match setIsMatch:YES forObject:anObject];
    return [match autorelease];   /* Let match go and return it. */
fi0 }
pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 fs28 fs16 
fs28 By retaining b matchb0  while b subpoolb0  is in effect and autoreleasing it after the b subpoolb0  has been released, b matchb0  is effectively moved from b subpoolb0  to the pool that was previously in effect. This gives it a longer lifetime and allows it to be sent messages outside the loop and to be returned to the invoker of b findMatchingObject:b0 .
fs16 
fs28 pard s15 li477 fi0 ri1007 ql f0 b fs24 fs4 
fs24 General Exception Conditions
pard s1 li477 fi0 ri1007 ql tx2494 tx2872 tx3250 f1 b0 fs28 fs16 
fs28 An NSInvalidArgumentException is raised on any attempt to send either b retainb0  or b autoreleaseb0  messages to an autorelease pool object. 
fs16 
fs28 pard s16 li100 fi0 ri1007 ql f0 b fs24 
fs28 Adding an Object to the Current Pool 
fs14 
fs28 pard s8 li7029 fi-6552 ri1007 ql tx6652 tx7030 f1 b0 fs2 
fs28 fi-6552 + (void)b addObject:b0 (id)i anObjecti0 tab Adds i anObjecti0  to the active autorelease pool in the current thread.
pard s16 li100 fi0 ri1007 ql f0 b fs48 
fs28 Adding an Object to a Pool 
fs14 
fs28 pard s8 li7029 fi-6552 ri1007 ql tx6652 tx7030 f1 b0 fs2 
fs28 fi-6552 {f3 -} (void)b addObject:b0 (id)i anObjecti0 tab Adds i anObjecti0  to the receiver.
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.