Program received signal: “EXC_BAD_ACCESS”

Discussion in 'iOS Programming' started by skunkio, Apr 27, 2010.

  1. skunkio macrumors newbie

    Joined:
    Apr 25, 2010
    #1
    Hi all,
    my app generates this error: EXC_BAD_ACCESS
    Checking internet i see the problem can be:

    * access protected or non-existent memory space as result of a bad pointer
    * access memory without alloc init
    * access memory after released object
    * remove the [object release] only if you don’t use alloc/copy/retain
    * trying to access release objects
    * illegal memory access

    so looks like very clear i'm reading something "can not be read".
    My app is very simple and has only a table with two elements inside. Touching the item a second view will appear showing details about the item touched (inside two different text boxes). Changing the text and touching a save button the table will appear again and the item will be updated.
    I receive this exception sometimes after touching the button save sometimes touching the item within the table.
    How can i see which instruction generates the error?

    This is the save button code:
    Code:
    - (void) save
    {
    	self.event.name = self.name.text;
    	self.event.description = self.description.text;
    	
    	[self.navigationController popViewControllerAnimated:YES];
    }
    this is the table item touch:
    Code:
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {	
    	selectedEvent = [listEvents objectAtIndex:indexPath.row];
    	self.eventController.event = selectedEvent;
    	
    	[self.navigationController pushViewController:eventController animated:YES];
    }
    this is the code i use to update the table:
    Code:
    - (void)viewWillAppear:(BOOL)animated {
    	[super viewWillAppear:animated];
    	
    	if (selectedEvent != nil) {
    		NSIndexPath *updatePath = [NSIndexPath indexPathForRow:[listEvents indexOfObject:selectedEvent] inSection:0];
    	
    		NSArray *updatePaths = [NSArray arrayWithObject:updatePath];
    		[self.tableView reloadRowsAtIndexPaths:updatePaths withRowAnimation:NO];
    	
    		selectedEvent = nil;
    	}
    }
    and this is the code i use to fill the table:
    Code:
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        listEvents = [[NSMutableArray alloc] init];	
        Event *event = [[Event alloc] initWithName:@"Primo evento" description:@"Questo è il primo evento inserito"];
        [listEvents addObject:event]; 
        Event *event2 = [[Event alloc] initWithName:@"Secondo evento" description:@"Questo è il secondo evento inserito"];
        [listEvents addObject:event2];
    	
        EventViewController *newEventController = [[EventViewController alloc] init];
        self.eventController = newEventController;
        //EventViewController *eventController = [[EventViewController alloc] init];
    	
        Event *selectedEvent = [Event alloc];
    	
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        self.navigationItem.leftBarButtonItem = self.editButtonItem;
    }
    
    Thanks,
    stè
     
  2. skunkio thread starter macrumors newbie

    Joined:
    Apr 25, 2010
    #2
    The red row in:

    Code:
    - (void) viewWillAppear: (BOOL) animated {
    	[super viewWillAppear:animated];
    	
    [COLOR="Red"]	self.name.text = self.event.name;[/COLOR]
    	self.description.text = self.event.description;
    }
    
    generates now the error.
    self.event looks like null (not valid) but i don't understand why.


    Thanks,
    stè
     
  3. skunkworker macrumors regular

    Joined:
    Sep 9, 2007
    #3
    Are you using a @property with a retain value for whatever file its in?
     
  4. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #4
    Where is self.event set? And with what value? Did you check the value in the debugger when this variable was set to see if it was actually set when and with what you think it should have?
     
  5. skunkio thread starter macrumors newbie

    Joined:
    Apr 25, 2010
    #5
    yes, this is the interface the defines my property event inside the eventViewController class

    Code:
    #import <UIKit/UIKit.h>
    
    @class Event;
    
    @interface EventViewController : UIViewController <UITextFieldDelegate> {
    	UITextField *name;
    	UITextField *description;
    	Event *event;
    }
    
    
    @property (nonatomic, retain) IBOutlet UITextField *name;
    @property (nonatomic, retain) IBOutlet UITextField *description;
    @property (nonatomic, retain) Event *event;
    
    - (IBAction) save;
    
    @end
    Thanks,
    stè
     
  6. kaydell.leavitt macrumors regular

    Joined:
    Apr 19, 2010
    #6
    Are you releasing an object and then subsequently using it?

    -- Kaydell
     
  7. skunkworker macrumors regular

    Joined:
    Sep 9, 2007
    #7
    Are you sure you are creating and initializing the event object?
    What are your event constructors and inits?
     
  8. skunkio thread starter macrumors newbie

    Joined:
    Apr 25, 2010
    #8
    I updated my code but i'm not really understanting has been managed.
    My application, now, after touch the two items closes itself without generating errors (i don't see nothing within the console and the debugger doesn't give me indication about errors). Here my lates code:

    This is my event class, pretty simple, has only one method and exposes two properties

    Event.h
    Code:
    #import <Foundation/Foundation.h>
    
    @interface Event : NSObject {
    	NSString *name;
    	NSString *description;
    }
    
    @property (nonatomic, retain) NSString *name;
    @property (nonatomic, retain) NSString *description;
    
    - (id) initWithName: (NSString *) newName
    	    description: (NSString *) newDescription;
    
    @end
    Event.m
    Code:
    #import "Event.h"
    
    @implementation Event
    
    @synthesize name, description;
    
    - (id) initWithName: (NSString *) newName
    	    description: (NSString *) newDescription
    {
    	self = [super init];
    	
    	if (self != nil) {
    		self.name = newName;
    		self.description = newDescription;
    	}
    	
    	return self;
    }
    
    @end
    This is my EventController class; a view with two text fields inside and one button. The view shows some info about the item touched over a table and the buttom save close che view.
    This class exposes one method and one property defined as Event type (described above)

    EventController.h
    Code:
    @class Event;
    
    @interface EventViewController : UIViewController <UITextFieldDelegate> {
    	UITextField *name;
    	UITextField *description;
    	Event *event;
    }
    
    @property (nonatomic, retain) IBOutlet UITextField *name;
    @property (nonatomic, retain) IBOutlet UITextField *description;
    @property (nonatomic, retain) Event *event;
    
    - (IBAction) save;
    
    @end
    EventController.m
    Code:
    #import "EventViewController.h"
    #import "Event.h"
    
    @implementation EventViewController
    
    @synthesize name, description;
    @synthesize event;
    
    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
    - (void)viewDidLoad {
        [super viewDidLoad];	
    }
    
    - (void) viewWillAppear: (BOOL) animated {
    	[super viewWillAppear:animated];
    	
    	self.name.text = self.event.name;
    	self.description.text = self.event.description;
    }
    
    - (void) save
    {
    	self.event.name = self.name.text;
    	self.event.description = self.description.text;
    	
    	[self.navigationController popViewControllerAnimated:YES];
    }
    
    - (BOOL) textFieldShouldReturn: (UITextField *) textField
    {
    	[textField resignFirstResponder];
    	return YES;
    }
    
    - (void)didReceiveMemoryWarning {
    	// Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
    	
    	// Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
    	// Release any retained subviews of the main view.
    	// e.g. self.myOutlet = nil;
    	self.name = nil;
    	self.description = nil;
    }
    
    - (void)dealloc {	
        [super dealloc];
    }
    
    @end
    Finally, this is my table view (my first view). There are two items inside a grid, touching the grid the EventController view appears showing some details about the item touched

    RootViewController.h
    Code:
    @class Event;
    @class EventViewController;
    
    @interface RootViewController : UITableViewController {
    	NSMutableArray *listEvents;
    	Event *selectedEvent;
    	NSString *text;
    
    	EventViewController *eventController;
    }
    
    @property (nonatomic, retain) EventViewController *eventController;
    
    @end
    RootViewController.m
    Code:
    #import "RootViewController.h"
    #import "Event.h";
    #import "EventViewController.h";
    
    @implementation RootViewController
    
    @synthesize eventController;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
    	listEvents = [[NSMutableArray alloc] init];
    	eventController = [[EventViewController alloc] init];
    	
    	//eventController.event = [[Event alloc] init];
    	
    	Event *event1 = [[Event alloc] initWithName:@"Primo evento" description:@"Questo è il primo evento inserito"];
    	[listEvents addObject:event1];
    	//[event release];
    
    	Event *event2 = [[Event alloc] initWithName:@"Secondo evento" description:@"Questo è il secondo evento inserito"];
    	[listEvents addObject:event2];	
    	
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        self.navigationItem.leftBarButtonItem = self.editButtonItem;
    }
    
    - (void)viewWillAppear:(BOOL)animated {
    	[super viewWillAppear:animated];
    	
    	if (selectedEvent != nil) {
    		NSIndexPath *updatePath = [NSIndexPath indexPathForRow:[listEvents indexOfObject:selectedEvent] inSection:0];
    	
    		NSArray *updatePaths = [NSArray arrayWithObject:updatePath];
    		[self.tableView reloadRowsAtIndexPaths:updatePaths withRowAnimation:NO];
    	
    		selectedEvent = nil;
    	}
    }
    
    - (void)didReceiveMemoryWarning {
    	// Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
    	
    	// Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
    	// Release anything that can be recreated in viewDidLoad or on demand.
    	// e.g. self.myOutlet = nil;
    }
    
    
    #pragma mark Table view methods
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 1;
    }
    
    // Customize the number of rows in the table view.
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [listEvents count];
    }
    
    // Customize the appearance of table view cells.
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        }
        
    	// Configure the cell.
    	Event *event = [listEvents objectAtIndex:indexPath.row];
    	cell.textLabel.text = event.name;
    	[event release];
    	
        return cell;
    }
    
    // Override to support row selection in the table view.
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    	selectedEvent = [listEvents objectAtIndex:indexPath.row];
    	eventController.event = selectedEvent;
    
    	[self.navigationController pushViewController:eventController animated:YES];
    }
    
    // Override to support conditional editing of the table view.
    - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
        // Return NO if you do not want the specified item to be editable.
        return YES;
    }
    
    // Override to support editing the table view.
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
        
        if (editingStyle == UITableViewCellEditingStyleDelete) {
            // Delete the row from the data source.
    		[listEvents removeObjectAtIndex:indexPath.row];
    		[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }   
        //else if (editingStyle == UITableViewCellEditingStyleInsert) {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
        //}   
    }
    
    - (void)dealloc {
    	//[selectedEvent dealloc];
        [super dealloc];
    }
    
    @end
    I don't know hot to initialize Event inside EventController properly, so i tried this line:

    eventController.event = [[Event alloc] init];

    but hasn't effects.
    I want initialize EventController and inside this class i want create also the Event object. I tried also in the viewDidLoad but doesn't work.


    Ciao,
    stè
     
  9. skunkio thread starter macrumors newbie

    Joined:
    Apr 25, 2010
    #9
    My code looks like working if i remove the red line below

    RootViewController.m
    Code:
    [cut...]
    // Customize the appearance of table view cells.
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        }
        
    	// Configure the cell.
    	Event *event = [listEvents objectAtIndex:indexPath.row];
    	cell.textLabel.text = event.name;
    	[COLOR="Red"][event release];[/COLOR]
    	
        return cell;
    }
    to me this comportment is totally without sense.

    Ciao,
    stè
     
  10. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #10
    There is no need for you to release event since you never alloc/init'd it in the first place. Make sure you have read the Memory Management Programming Guide for Cocoa.
     

Share This Page