I don't get hoped for messages from gdb
XCode 3.2.5
OS X 10.6.5
My universal app is a standard drill down app with three levels:
1.List of Types (in a Table)
2.List of Objects with Type Choosen (in a Table)
3.Details of Choosen with Tabbed View.
App repeatedly goes up and down levels successfully. The problem happens only after
I load multiple photos in a couple of the Tabs of Level 3 and the return
to Level 2. I assume this higher demand for memory causes the problem.
The first sign of trouble is the second message
message:
2010-12-31 13:40:40.812 myApp[1533:307] NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!
2010-12-31 13:40:57.185 myApp[1533:307] Received memory warning. Level=1
The symptoms are that the TableView Level 2 is sometimes empty. When it is empty,
the problem is always fixed by restarting the app.
The following methods are called on Level 2's tableView during each
of these "no load" calls:
- (NSInteger)tableView: (UITableView *)tv numberOfRowsInSection

NSInteger)section
- (NSInteger)numberOfSectionsInTableView: (UITableView *)tv
The first of these methods return the value > 0 each time called.
The second method returns the value 1 each time it is called.
I believe this calls for using NSZombies. I have used the following
in .gdbinit
----------begin
fb -[NSException raise]
fb -[NSAssertionHandler handleFailureInFunction:file:lineNumber:descriptio n:]
fb -[NSAssertionHandler handleFailureInMethod

bject:file:lineNumber:descr iption:]
#define NSZombies
# this will give you help messages. Set to NO to turn them off.
set env MallocHelp=YES
# might also be set in launch arguments.
set env NSZombieEnabled=YES
set env NSDeallocateZombies=NO
set env MallocCheckHeapEach=100000
set env MallocCheckHeapStart=100000
set env MallocScribble=YES
set env MallocGuardEdges=YES
set env MallocCheckHeapAbort=1
set env MallocCorruptionAbort=YES
set env MallocErrorAbort=YES
set env CFZombie 5
fb -[_NSZombie init]
fb -[_NSZombie retainCount]
fb -[_NSZombie retain]
fb -[_NSZombie release]
fb -[_NSZombie autorelease]
fb -[_NSZombie methodSignatureForSelector:]
fb -[_NSZombie respondsToSelector:]
fb -[_NSZombie forwardInvocation:]
fb -[_NSZombie class]
fb -[_NSZombie dealloc]
fb szone_error
--------end
The app continues to run, with Level 2's tableView empty.
I receive no more errors.
The DataSource for the UITableView is never empty.
When the TableView on Level 2 is empty, there are
no TableView delegate methods called other than the
two mentioned above.
// The following method at Level 1 pushes viewController to reach Level 2
- (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
iHungry_MeAppDelegate* theAppDel = [[UIApplication sharedApplication] delegate];
Category *aCategory = (Category*)[dataSourceCategoryArray objectAtIndex:[indexPath row]];
if(dataSourceCategoryArray==nil){
NSLog(@"RTVC:dataSourceCategoryArray==nil");
}
[[self subListViewController] setActiveCategory : aCategory];
[theAppDel setActiveCategory:aCategory];
UINavigationController *navController = [theAppDel navigationController];
[navController pushViewController:subListViewController animated:YES];
}
// The following method causes Level 2's UITableView to populate
// This method is called correctly both before and after the error occurs
- (void)viewWillAppear: (BOOL)animated {
[super viewWillAppear:animated];
[self.navigationItem.rightBarButtonItem setTitle: @"Edit"];
[[self navigationItem] setHidesBackButton:NO];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
BOOL bRandomRecipe = [prefs boolForKey:@"Random_Recipe"];
if(bRandomRecipe){
[self.accelerometer setDelegate: self];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(handleTableViewSelectionDidChan ge
name:UITableViewSelectionDidChangeNotification
object:self];
}
if ([self activeCategory] == nil) {
NSLog(@"SLVC:viewWillAppear: activeCategory is nil.");
exit(-2);
}
[self updateRecipeArrayGlobal];//namely [appDel recipeArray]
[self updateRecipeArrayLocal:[self activeCategory]];// [self dataSourceRecipeArray]
NSString* catTitle;
catTitle = [NSString stringWithFormat:@"%@ (%d)",[[self activeCategory] name]
,[[self dataSourceRecipeArray] count]];
[self setTitle:catTitle];
[tableView reloadData];
}
// The following method causes the DataSource Array for TableView Level 2 to be built
// This method is called correctly both before and after the error occurs
- (void) updateRecipeArrayLocal: (Category*) categ {
NSArray *filteredRecipeArray;
iHungry_MeAppDelegate* appDel =
(iHungry_MeAppDelegate*)[[UIApplication sharedApplication] delegate];
NSPredicate* predicate;
NSComparisonResult result = [[[self activeCategory] name] compare:@"Browse All"];
if(result != NSOrderedSame){
predicate = [NSPredicate predicateWithFormat:
@"ANY SELF.categories == %@", [self activeCategory]]; //Any Recipe with a category == activeCat
filteredRecipeArray = [[appDel recipeArray] filteredArrayUsingPredicate

redicate];
[self setDataSourceRecipeArray:filteredRecipeArray];
}else {
[self setDataSourceRecipeArray:[appDel recipeArray]];//Category is 'Browse All' so load ALL recipes
}
}
// The following method causes the cells of TableView Level 2 to be configured
// This method is called correctly before the error occurs but not after
- (UITableViewCell *)tableView: (UITableView *)tv cellForRowAtIndexPath: (NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"MyIdentifier"] ;
[cell autorelease];
}
if([[self dataSourceRecipeArray] count] > indexPath.row){
Recipe *aRecipe = [[self dataSourceRecipeArray] objectAtIndex: indexPath.row];
[cell.textLabel setText:aRecipe.name];
cell.editingAccessoryType=UITableViewCellAccessory DetailDisclosureButton;
}else{
[cell.textLabel setText:@"add recipe"];
cell.editingAccessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Can someone please give me a pointer on how to track down this intermittent problem.
Many Thanks, Mark