This is the first time I have created an application for the iPhone, and I have difficulty managing memory because I have never had to deal with it before.
I have a UITableViewController and everything works fine until I try to scroll down in the simulator. He falls, saying that he cannot allocate so much memory. I narrowed it to the scene:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // Dequeue or create a cell UITableViewCellStyle style = UITableViewCellStyleDefault; UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:@"BaseCell"]; if (!cell) cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:@"BaseCell"] autorelease]; NSString* crayon; // Retrieve the crayon and its color if (aTableView == self.tableView) { crayon = [[[self.sectionArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] getName]; } else { crayon = [FILTEREDKEYS objectAtIndex:indexPath.row]; } cell.textLabel.text = crayon; if (![crayon hasPrefix:@"White"]) cell.textLabel.textColor = [self.crayonColors objectForKey:crayon]; else cell.textLabel.textColor = [UIColor blackColor]; return cell; }
Here is the getName method:
- (NSString*)getName { return name; }
name is defined as:
@property (nonatomic, retain) NSString *name;
Now sectionArray is an NSMutableArray with instances of the class in which I created Term in it.
The term has a getName method that returns NSString *. It seems that the problem is where the pencil is set and getName is called. I tried to add autorelease , release, and other similar things, but this just causes the whole application to crash before it starts.
Also, if:
cell.textLabel.text = @"test"; //crayon; /*if (![crayon hasPrefix:@"White"]) cell.textLabel.textColor = [self.crayonColors objectForKey:crayon]; else cell.textLabel.textColor = [UIColor blackColor];*/
Then I get no error, and it all scrolls just fine.
Thanks in advance for your help!
Edit:
Here is the full log when I try to run the application and the error it gives when it crashes:
[The session began on 2010-12-29 04:23:38 -0500.]
[Session started on 2010-12-29 04:23:44 -0500.] GNU gdb 6.3.50-20050815 (Apple version gdb-967) (Tue Jul 14 02:11:58 UTC 2009) Copyright 2004 Free Software Foundation , Inc. GDB is free software covered by the GNU General Public License, and you are welcome to modify it and / or distribute it under certain conditions. Type "show copy" to see the conditions. There are absolutely no guarantees for GDB. Enter "show warranty" for more information. This GDB was configured as "i386-apple-darwin" .sharedlibrary apply-load-rules all Attachment to process 1429. gdb-i386-apple-darwin (1430,0x778720) malloc: * mmap (size = 1420296192) failed (code errors = 12) : cannot highlight area ** set breakpoint in malloc_error_break for debugging scan gdb stack at internal error point: [0] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexec/gdb/gdb-i386- apple-darwin (align_down + 0x0) [0x1222d8] [1] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexec/gdb/gdb-i386-apple-darwin (xstrvprintf + 0x0) [0x12336c] Developer / Platforms / iPhoneSimulator.platform / Developer / usr / libexec / gdb / gdb-i386-apple-darwin (xmalloc + 0x28) [0x12358f] [3] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexec/gdb / gdb-i386-apple-darwin (dyld_in fo_read_raw_data + 0x50) [0x1659af] [4] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexec/gdb/gdb-i386-apple-darwin (dyld_info_read + 0x1bc) [0x16858 /] / Platform] /] iPhoneSimulator.platform / Developer / usr / libexec / gdb / gdb-i386-apple-darwin (macosx_dyld_update + 0xbf) [0x168c9c] [6] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexbg -apple-darwin (macosx_solib_add + 0x36b) [0x169fcc] [7] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexec/gdb/gdb-i386-apple-darwin (macosx_child17attacht11_tach_11dacht) 11dacht_11ach_attach_11ach_attach_11ach_attach_11ach /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexec/gdb/gdb-i386-apple-darwin (attach_command + 0x5d) [0x64ec5] [9] /Developer/Platforms/iPhoneSimulator.platform/Dib/ gdb / gdb-i386-apple-darwin (mi_cmd_target_attach + 0x4c) [0x15dbd] [10] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexec/gdb/gdb-i386-apple-dmx 0 (0) 0x17427] [11] / Deve loper / Platforms / iPhoneSimulator.platform / Developer / usr / libexec / gdb / gdb-i386-apple-darwin (catch_exception + 0x41) [0x7a99a] [12] /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/libexecgd / gdb-i386-apple-darwin (mi_execute_command + 0xa9) [0x16f63] / SourceCache / gdb / gdb -967 / src / gdb / utils.c: 1144: internal error: virtual memory has been exhausted: 1420296192 bytes could not be allocated. A problem has been discovered that is internal to GDB, further debugging may not be reliable.
The debugger exited with status 1. The debugger exited with status 1.
Here is the backtrace that I get when I set a breakpoint for malloc_error_break:
#0 0x0097a68c in objc_msgSend () #1 0x01785bef in -[UILabel setText:] () #2 0x000030e0 in -[TableViewController tableView:cellForRowAtIndexPath:] (self=0x421d760, _cmd=0x29cfad8, aTableView=0x4819600, indexPath=0x42190f0) at /Volumes/Main2/Enayet/TableViewController.m:99 #3 0x016cee0c in -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] () #4 0x016c6a43 in -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] () #5 0x016d954f in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow] () #6 0x016d08ff in -[UITableView layoutSubviews] () #7 0x03e672b0 in -[CALayer layoutSublayers] () #8 0x03e6706f in CALayerLayoutIfNeeded () #9 0x03e668c6 in CA::Context::commit_transaction () #10 0x03e6653a in CA::Transaction::commit () #11 0x03e6e838 in CA::Transaction::observer_callback () #12 0x00b00252 in __CFRunLoopDoObservers () #13 0x00aff65f in CFRunLoopRunSpecific () #14 0x00afec48 in CFRunLoopRunInMode () #15 0x00156615 in GSEventRunModal () #16 0x001566da in GSEventRun () #17 0x01689faf in UIApplicationMain () #18 0x00002398 in main (argc=1, argv=0xbfffefb0) at /Volumes/Main2/Enayet/main.m:14
--------
Here is my complete source for the UITableViewController class:
// // TableViewController.m // Enayet // // Created by Filip on 12/27/10. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import "TableViewController.h" #import "EnayetAppDelegate.h" @implementation TableViewController @synthesize crayonColors; @synthesize filteredArray; @synthesize sectionArray; @synthesize searchBar; @synthesize searchDC; - (TableViewController*) initToCall:(NSMutableDictionary*) toUseArray { self = [super initWithStyle:UITableViewStylePlain]; crayonColors = toUseArray; return self; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView { if (aTableView == self.tableView) return 26; return 1; } // Via Jack Lucky - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { [self.searchBar setText:@""]; } - (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section { if (aTableView == self.tableView) { if ([[self.sectionArray objectAtIndex:section] count] == 0) return nil; //return [NSString stringWithFormat:@"%@", [[ALPHA substringFromIndex:section] substringToIndex:1]]; return [[ALPHA substringFromIndex:section] substringToIndex:1]; } else return nil; } - (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { // Normal table if (aTableView == self.tableView) return [[self.sectionArray objectAtIndex:section] count]; // Search table NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", self.searchBar.text]; self.filteredArray = [self.crayonColors.allKeys filteredArrayUsingPredicate:predicate]; return self.filteredArray.count; } // Convert a 6-character hex color to a UIColor object - (UIColor *) getColor: (NSString *) hexColor { unsigned int red, green, blue; NSRange range; range.length = 2; range.location = 0; [[NSScanner scannerWithString:[hexColor substringWithRange:range]] scanHexInt:&red]; range.location = 2; [[NSScanner scannerWithString:[hexColor substringWithRange:range]] scanHexInt:&green]; range.location = 4; [[NSScanner scannerWithString:[hexColor substringWithRange:range]] scanHexInt:&blue]; return [UIColor colorWithRed:(float)(red/255.0f) green:(float)(green/255.0f) blue:(float)(blue/255.0f) alpha:1.0f]; } - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // Dequeue or create a cell UITableViewCellStyle style = UITableViewCellStyleDefault; UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:@"BaseCell"]; if (!cell) cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:@"BaseCell"] autorelease]; NSString* crayon; // Retrieve the crayon and its color if (aTableView == self.tableView) { Term *term = (Term *) [[self.sectionArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; crayon = [term name]; } else { crayon = [FILTEREDKEYS objectAtIndex:indexPath.row]; } cell.textLabel.text = crayon; if (![crayon hasPrefix:@"White"]) cell.textLabel.textColor = [self.crayonColors objectForKey:crayon]; else cell.textLabel.textColor = [UIColor blackColor]; return cell; } // Grouped Tables do not support section indices (even though they kind of do) - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)aTableView { if (aTableView == self.tableView) // regular table { NSMutableArray *indices = [NSMutableArray arrayWithObject:UITableViewIndexSearch]; for (int i = 0; i < 26; i++) if ([[self.sectionArray objectAtIndex:i] count]) [indices addObject:[[ALPHA substringFromIndex:i] substringToIndex:1]]; // [indices addObject:@"\ue057"]; // <-- using emoji return indices; } else return nil; // search table } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { if (title == UITableViewIndexSearch) return 0; return [ALPHA rangeOfString:title].location; } - (void)goToTwo:(Term*) toGive { EnayetAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; [appDelegate setTerm:toGive]; [appDelegate displayView:2]; } // Respond to user selections by updating tint colors - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (aTableView == self.tableView) { [self goToTwo:[[self.sectionArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]]; } } - (void) viewDidLoad { // Prepare the crayon color dictionary NSString *pathname = [[NSBundle mainBundle] pathForResource:@"crayons" ofType:@"txt" inDirectory:@"/"]; NSArray *rawCrayons = [[NSString stringWithContentsOfFile:pathname encoding:NSUTF8StringEncoding error:nil] componentsSeparatedByString:@"\n"]; self.crayonColors = [NSMutableDictionary dictionary]; self.sectionArray = [NSMutableArray array]; for (int i = 0; i < 26; i++) [self.sectionArray addObject:[NSMutableArray array]]; for (NSString *string in rawCrayons) { [self.crayonColors setObject:CRAYON_COLOR(string) forKey:CRAYON_NAME(string)]; NSUInteger firstLetter = [ALPHA rangeOfString:[string substringToIndex:1]].location; if (firstLetter != NSNotFound) [[self.sectionArray objectAtIndex:firstLetter] addObject:[[Term alloc] initToCall:CRAYON_NAME(string)]]; } //NSLog(@"%@", sectionArray); // Create a search bar self.searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)] autorelease]; self.searchBar.tintColor = COOKBOOK_PURPLE_COLOR; self.searchBar.autocorrectionType = UITextAutocorrectionTypeNo; self.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone; self.searchBar.keyboardType = UIKeyboardTypeAlphabet; self.tableView.tableHeaderView = self.searchBar; // Create the search display controller self.searchDC = [[[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self] autorelease]; self.searchDC.searchResultsDataSource = self; self.searchDC.searchResultsDelegate = self; } @end
------
Here is my Term.m file:
// // Term.m // Enayet // // Created by Filip on 12/27/10. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import "Term.h" @implementation Term @synthesize name; - (Term*)initToCall:(NSString*) toSetName { name = toSetName; return self; } - (NSString*)getName { return name; } -(void)dealloc { [name release]; [super dealloc]; } @end