OK. I did a google search on "NSAutoreleaseNoPool sortUsingDescriptors" and got nothing but one broken link.
I have an optimizer that uses the parent and children analogy. A NSMutableArray ("thePopulation") holds individual custom objects. When optimizing, I make another NSMutableArray called "theGenePool" using setArray:thePopulation. Then, in the runAGeneration method I take 2 objects from theGenePool, use them to make children (new objects, sharing attributes from each 'parent'), and add those children to thePopulation. The parents are removed from theGenePool once they are used.
This way I can keep track of which 'parent' objects in thePopulation haven't been used yet, while leaving those same parents still in thePopulation array.
My problem happens before I get to the runAGeneration method, however, so the details of that method are unimportant. In the code (below) I get lots of errors saying:
Please note - I have an NSAutoreleasePool in both the calling View object and in the optimize method in the Controller object so there *is* a pool. Each of my custom objects that are in theGenePool use 3 arrays of (floats), with 21 floats in each array, so I am confused why I get only a single "NSNumber" being autoreleased with each object in theGenePool array. I assume that the sortUsingDescriptor method uses a NSNumber for each object in the array it is sorting. Also, to clarify, I use a breakpoint to stop the execution as it enters the optimize method. Then I watch the debugger console as I single step through the optimize method. I get no errors at all until I step over the sortUsingDescriptors line, at which point I get one error per object and 2 more to boot (20 objects = 22 errors, 40 objects = 42 errors, etc.).
Here is my View object. I have 2 buttons, one of which runs the optimizer normally and the other runs the same optimizer (exactly) in a thread. That is the only difference between "runNormal" and "runThreaded". As you can see, the "runThreaded" method adds an NSAutoreleasePool but is otherwise identical to the "runNormal" method.
The optimize function is in the controller, aptly named "myController". The "fertilityAllocation" goes through the array and changes a single variable held by each object called "numOfKids" that determines how many children each parent can have. It has no other effect on the objects. Here is the code with the offending line in red:
The error I get in the debugger window is as follows. I include 8 messages to show that they are all the exact same message. I get one message per object in the array theGenePool when I hit the sortUsingDescriptors method:
Bottom line: how in the world do I debug this?!? I have an autorelease pool in place. I can't step into the sortUsingDescriptors method and the method works just fine (well - no errors in the debugger console, at any rate) when I run the normal method. I am using threading so I can update the GUI as progress is made.
I have an optimizer that uses the parent and children analogy. A NSMutableArray ("thePopulation") holds individual custom objects. When optimizing, I make another NSMutableArray called "theGenePool" using setArray:thePopulation. Then, in the runAGeneration method I take 2 objects from theGenePool, use them to make children (new objects, sharing attributes from each 'parent'), and add those children to thePopulation. The parents are removed from theGenePool once they are used.
This way I can keep track of which 'parent' objects in thePopulation haven't been used yet, while leaving those same parents still in thePopulation array.
My problem happens before I get to the runAGeneration method, however, so the details of that method are unimportant. In the code (below) I get lots of errors saying:
Code:
_NSAutoreleaseNoPool(): Object 0x1b7170 of class NSCFNumber autoreleased with no pool in place - just leaking
Please note - I have an NSAutoreleasePool in both the calling View object and in the optimize method in the Controller object so there *is* a pool. Each of my custom objects that are in theGenePool use 3 arrays of (floats), with 21 floats in each array, so I am confused why I get only a single "NSNumber" being autoreleased with each object in theGenePool array. I assume that the sortUsingDescriptor method uses a NSNumber for each object in the array it is sorting. Also, to clarify, I use a breakpoint to stop the execution as it enters the optimize method. Then I watch the debugger console as I single step through the optimize method. I get no errors at all until I step over the sortUsingDescriptors line, at which point I get one error per object and 2 more to boot (20 objects = 22 errors, 40 objects = 42 errors, etc.).
Here is my View object. I have 2 buttons, one of which runs the optimizer normally and the other runs the same optimizer (exactly) in a thread. That is the only difference between "runNormal" and "runThreaded". As you can see, the "runThreaded" method adds an NSAutoreleasePool but is otherwise identical to the "runNormal" method.
Code:
// IBActions
-(IBAction)runNormal: (id)sender
{
// Clear a NSMutableArray instance variable before each run
if ([myHallOfFame count] > 0)
[myHallOfFame removeAllObjects];
// Update the GUI based on input from the user.
[self setupMeters];
[numOneView setIndi:nil];
[numTwoView setIndi:nil];
[numThreeView setIndi:nil];
[currentView setIndi:nil];
[hallOfFameView setIndi:nil];
// This is my controller object - it gets its initial values from the GUI textFields (boxes)
myController = [[EvoOptimController alloc] initWithParents:[numOfParents intValue]
facets:[numOfFacets intValue]
maxPop:[maxPop intValue]
initPop:[initPop intValue]
warFreq:[warFreq intValue]
MGWOI:[GWOI intValue]
minGen:[minGen intValue]
minImprov:[minImprove floatValue]
Delta:[delta floatValue]
Environ: self];
// Here is where the 'work' gets done, in the "optimize" method.
[myController optimize];
// Released to balance the 'alloc' above.
[myController release];
}
-(IBAction)runThreaded: (id)sender
{
// Autorelease pool used for threading
NSAutoreleasePool * viewReleasePool = [[NSAutoreleasePool alloc] init];
// Clear a NSMutableArray instance variable before each run
if ([myHallOfFame count] > 0)
[myHallOfFame removeAllObjects];
// Update the GUI based on input from the user.
[self setupMeters];
[numOneView setIndi:nil];
[numTwoView setIndi:nil];
[numThreeView setIndi:nil];
[currentView setIndi:nil];
[hallOfFameView setIndi:nil];
myController = [[EvoOptimController alloc] initWithParents:[numOfParents intValue]
facets:[numOfFacets intValue]
maxPop:[maxPop intValue]
initPop:[initPop intValue]
warFreq:[warFreq intValue]
MGWOI:[GWOI intValue]
minGen:[minGen intValue]
minImprov:[minImprove floatValue]
Delta:[delta floatValue]
Environ: self];
// Same as "runNormal" but creates a thread for the optimize method.
[myController performSelectorInBackground:@selector(optimize) withObject:nil];
[myController release];
[viewReleasePool release];
}
The optimize function is in the controller, aptly named "myController". The "fertilityAllocation" goes through the array and changes a single variable held by each object called "numOfKids" that determines how many children each parent can have. It has no other effect on the objects. Here is the code with the offending line in red:
Code:
-(void)optimize
{
// Autorelease pool for threading.
NSAutoreleasePool * optimizeReleasePool = [[NSAutoreleasePool alloc] init];
int gen = 0, // the generation of then new individuals
i; // Counters
srandomdev();
GWOI = 0;
[self setNumOne:[thePopulation objectAtIndex:0]];
[self setNumTwo:[thePopulation objectAtIndex:1]];
[self setNumThree:[thePopulation objectAtIndex:2]];
do
{
gen++;
// Explanation: thePopulation is a mutable array of custom objects. theGenePool copies
// thePopulation so it can remove objects (parents) as they get used, without directly changing
// thePopulation itself.
// Prep the genePool
[theGenePool setArray:thePopulation];
// Set the optimizing variables
baseDelta = [self determineBaseDelta];
deltaDelta = [self determineDD];
// Determine how many kids each parent can have based on ranking w/in the genePool
[self fertilityAllocation];
// Sort theGenePool by Score
[COLOR="red"][theGenePool sortUsingDescriptors:sortBy];[/COLOR]
// Run a single generation
[self runAGeneration: gen];
[optimizeReleasePool drain];
// Compare new thePopulation with old ranking Indi's and increment GWOI if no new #1
// If a new #1 is found during valleyJumpingMode or Desperation, then the last #1 was
// a local hero and needs to be added to the list of localHeroes.
// Add new # 1 to both the Controller HoF AND the View's HoF list.
if ([[thePopulation objectAtIndex:0] score] - [numOne score] > minImprovement)
{
if(GWOI > localPeakMode) [localHeroes addObject:numOne];
GWOI = 0;
[self setNumOne:[thePopulation objectAtIndex:0]];
[myView updateHallOfFameList:numOne];
[hallOfFame insertObject:numOne atIndex:0];
} // numOne
else GWOI++;
}
while (GWOI < maxGenWithOutImprovement || gen < minGens );
[optimizeReleasePool release];
} // optimize
The error I get in the debugger window is as follows. I include 8 messages to show that they are all the exact same message. I get one message per object in the array theGenePool when I hit the sortUsingDescriptors method:
Code:
2010-04-08 20:21:49.414 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x18e6b0 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
2010-04-08 20:21:49.427 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x18e6c0 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
2010-04-08 20:21:49.427 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x18e6d0 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
2010-04-08 20:21:49.435 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x18e6e0 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
2010-04-08 20:21:49.444 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x1610b610 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
2010-04-08 20:21:49.444 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x1610b620 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
2010-04-08 20:21:49.447 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x1610b630 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
2010-04-08 20:21:49.453 EvoOptim 5[1794:460b] *** _NSAutoreleaseNoPool(): Object 0x1610b640 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x92612f4f 0x9251f432 0x925495cb 0x92549067 0x92576c5a 0x92576842 0x925c1b64 0x2b20 0x92525dfd 0x925259a4 0x915ec155 0x915ec012)
Bottom line: how in the world do I debug this?!? I have an autorelease pool in place. I can't step into the sortUsingDescriptors method and the method works just fine (well - no errors in the debugger console, at any rate) when I run the normal method. I am using threading so I can update the GUI as progress is made.