3

I am getting a crash at line [selectedSession release]; in dealloc:

Default [NSCheapMutableString release]: message sent to deallocated instance

I don't understand why isn't this normal to put in dealloc?

All current code below:

LogViewController

    @implementation LogViewController

    @synthesize fetchedResultsController = __fetchedResultsController;
    @synthesize managedObjectContext;
    @synthesize logArray;
    @synthesize logTableView;
    @synthesize imageView;
    @synthesize session;
    @synthesize selectedSession;

    - (void)dealloc
    {
        [logArray release];
        [logTableView release];
        [session release];
        [__fetchedResultsController release];
        [managedObjectContext release];
        [imageView release];
        [selectedSession release];
        [super dealloc];
    }

    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
    }

    #pragma mark - View lifecycle

    - (void)viewDidLoad
    {
        self.logTableView.rowHeight = 47;
        [super viewDidLoad];
        self.navigationItem.title = @"Log";
        logTableView.backgroundColor = [UIColor clearColor];
        logTableView.separatorColor = [UIColor grayColor];
        self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:24/255.0 green:83/255.0 blue:170/255.0 alpha:1.0];
        self.logArray = [[NSArray alloc]initWithObjects:@"Today", @"Previous", @"Past Week", @"Past Month", @"All Workouts", nil];

        if (managedObjectContext == nil) 
        { 
            self.managedObjectContext = [(CurlAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
        }
    }

    - (void)viewDidUnload
    {
        self.logTableView = nil;
        self.fetchedResultsController = nil;
        self.imageView = nil;
        self.managedObjectContext = nil;
        [super viewDidUnload];
    }

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    }

    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    }

    - (void)viewDidDisappear:(BOOL)animated
    {
        [super viewDidDisappear:animated];
    }

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        // Return YES for supported orientations
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }

    #pragma mark - Table view data source


    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [self.logArray count];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        TDBadgedCell *cell = [[[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
        [self configureCell:cell atIndexPath:indexPath];
        return cell;
    }

    - (void)configureCell:(TDBadgedCell *)cell atIndexPath:(NSIndexPath *)indexPath
    {
        cell.textLabel.textColor = [UIColor blackColor];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell.textLabel.text = [logArray objectAtIndex:indexPath.row];
        cell.backgroundColor = [UIColor clearColor];
        cell.imageView.image = [UIImage imageNamed:@"17-bar-chart.png"];
        UIImageView *myImageView = nil;
        myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"silvercell5.png"]];
        [cell setBackgroundView:myImageView]; 
        [myImageView release];

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
        [dateFormatter setDateFormat:@"MMM d, y"]; 
        NSDate *date = nil;
        if (indexPath.row == 0)
        {
            date = [NSDate date]; 
            NSString *dateString = [dateFormatter stringFromDate:date]; 
            cell.badgeString = dateString;
        }
        else if (indexPath.row == 1)
        {
            if ([[self.fetchedResultsController fetchedObjects]count] > 1)
            {
                self.session = [[self.fetchedResultsController fetchedObjects]objectAtIndex:1];
                NSDate *date = self.session.timeStamp;
                NSString *dateString = [dateFormatter stringFromDate:date]; 
                cell.badgeString = dateString;
            }
            else
            {
                cell.badgeString = @"None";
            }
        }
        else if (indexPath.row > 1)
        {
            cell.badgeString = [NSString stringWithFormat:@"%i", [[self.fetchedResultsController fetchedObjects]count]];
        }
        cell.badgeColor = [UIColor colorWithRed:24/255.0 green:83/255.0 blue:170/255.0 alpha:1.0];
        [dateFormatter release]; 
    }

    #pragma mark - Table view delegate

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {    
        [tableView deselectRowAtIndexPath:indexPath animated:YES];

        if (indexPath.row == 0 || indexPath.row == 1)
        {
            SessionViewController *detailViewController = [[SessionViewController alloc] initWithNibName:@"SessionViewController" bundle:nil];
            detailViewController.title = [logArray objectAtIndex: indexPath.row];
            self.selectedSession = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
            detailViewController.selectedSession = self.selectedSession;
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
            [dateFormatter setDateFormat:@"MMM d, y"]; 
            NSString *dateString = [dateFormatter stringFromDate:selectedSession.timeStamp]; 
            detailViewController.title = dateString;
            [self.navigationController pushViewController:detailViewController animated:YES];
            [detailViewController release];
            [dateFormatter release];
        }
        else
        {
            LogResultsViewController *detailViewController = [[LogResultsViewController alloc] initWithNibName:@"LogResultsTableViewController" bundle:nil];
            detailViewController.title = [logArray objectAtIndex: indexPath.row];
            [self.navigationController pushViewController:detailViewController animated:YES];
            [detailViewController release];   
        }
    }
#pragma mark - Fetched results controller

- (NSFetchedResultsController *)fetchedResultsController
{
    if (fetchedResultsController != nil)
    {
        return fetchedResultsController;
    }

    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Session" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0] ;
    NSDate *today = [NSDate date]; 
    NSDate *thisWeek  = [today dateByAddingTimeInterval: -604800.0];
    NSDate *thisMonth = [today dateByAddingTimeInterval: -2629743.83]; // Use NSCalendar for

    if (indexPath.row ==2)
    {
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", thisWeek, today]];
    }
    else if (indexPath.row ==3)
    {
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", thisMonth, today]];
    }

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error])
    {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    NSLog(@"Number of Objects = %i",
           [[fetchedResultsController fetchedObjects] count]);
    return fetchedResultsController;
    NSLog(@"Number of Objects = %i",
          [[fetchedResultsController fetchedObjects] count]);

}    

#pragma mark - Fetched results controller delegate


- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.logTableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type)
    {
        case NSFetchedResultsChangeInsert:
            [self.logTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.logTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.logTableView;

    switch(type)
    {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.logTableView endUpdates];
}

LogResultsViewController

    @implementation LogResultsViewController
    @synthesize fetchedResultsController = __fetchedResultsController;
    @synthesize managedObjectContext;
    @synthesize resultsTableView;
    @synthesize selectedSession;

    - (void)dealloc
    {
        [__fetchedResultsController release];
        [managedObjectContext release];
        [selectedSession release];
        [resultsTableView release];
        [super dealloc];
    }

    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
    }

    #pragma mark - View lifecycle

    - (void)viewDidLoad
    {
        [super viewDidLoad];

        self.resultsTableView.separatorColor = [UIColor grayColor];

        self.resultsTableView.rowHeight = 50;

        [self managedObjectContext];
    }

    - (NSManagedObjectContext *)managedObjectContext 
    {
        if (managedObjectContext != nil) 
        {
            return managedObjectContext;
        }
        NSPersistentStoreCoordinator *coordinator = [(CurlAppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];   
        if (coordinator != nil) 
        {
            managedObjectContext = [[NSManagedObjectContext alloc] init];
            [managedObjectContext setPersistentStoreCoordinator:coordinator];
        }
        return managedObjectContext;
    }

    - (void)viewDidUnload
    {
        [super viewDidUnload];
        self.managedObjectContext = nil;
        self.fetchedResultsController = nil;
        self.resultsTableView = nil;
    }

    #pragma mark - Table view data source

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
        return [sectionInfo numberOfObjects];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        }    
        [self configureCell:cell atIndexPath:indexPath];
        return cell;
    }

    - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
    {
        Session *session = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
        [dateFormatter setDateFormat:@"eeee, MMM d, y"]; 
        NSString *dateString = [dateFormatter stringFromDate:session.timeStamp]; 

        NSDate *lastDate = session.timeStamp;
        NSDate *todaysDate = [NSDate date];
        NSTimeInterval lastDiff = [lastDate timeIntervalSinceNow];
        NSTimeInterval todaysDiff = [todaysDate timeIntervalSinceNow];
        NSTimeInterval dateDiff = todaysDiff-lastDiff;
        NSTimeInterval dayDifference = dateDiff/86400;
        int days = (int) dayDifference;
        NSLog(@"%i days",days);

        cell.textLabel.text = dateString;
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell.detailTextLabel.text = [NSString stringWithFormat: @"%i days ago", days];
        cell.detailTextLabel.textColor = [UIColor colorWithRed:24/255.0 green:83/255.0 blue:170/255.0 alpha:1.0];
        cell.imageView.image = [UIImage imageNamed:@"11-clock.png"];
        self.resultsTableView.tableFooterView = [[[UIView alloc] init] autorelease];

        UIImageView *myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"silvercell3.png"]];
        [cell setBackgroundView:myImageView];
        [dateFormatter release];
        [myImageView release];
    }

    -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (editingStyle == UITableViewCellEditingStyleDelete) 
        {
            // Delete the managed object for the given index path
            NSManagedObjectContext *context = [__fetchedResultsController managedObjectContext];
            [context deleteObject:[__fetchedResultsController objectAtIndexPath:indexPath]];

            // Commit the change.
            NSError *error = nil;

            // Update the array and table view.
            if (![managedObjectContext save:&error]) 
            {
                // Handle the error.
            }
            //[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: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;
    }

    #pragma mark - Table view delegate

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        SessionViewController *sessionViewController = [[SessionViewController alloc] initWithNibName:@"SessionViewController" bundle:nil];
        selectedSession = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
        sessionViewController.selectedSession = self.selectedSession;
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
        [dateFormatter setDateFormat:@"MMM d, y"]; 
        NSString *dateString = [dateFormatter stringFromDate:selectedSession.timeStamp]; 
        sessionViewController.title = dateString;

        [self.navigationController pushViewController:sessionViewController animated:YES];
        [sessionViewController release];
        [dateFormatter release];
    }
#pragma mark - Fetched results controller

- (NSFetchedResultsController *)fetchedResultsController
{
    if (fetchedResultsController != nil)
    {
        return fetchedResultsController;
    }

    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Session" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];


    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    NSError *error = nil;
    if (![fetchedResultsController performFetch:&error])
    {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    return fetchedResultsController;
}    

#pragma mark - Fetched results controller delegate


- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.resultsTableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type)
    {
        case NSFetchedResultsChangeInsert:
            [self.resultsTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.resultsTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.resultsTableView;

    switch(type)
    {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.resultsTableView endUpdates];
}

SessionViewController

@implementation SessionViewController

@synthesize exerciseArray;
@synthesize selectedSession;

- (void)dealloc
{
    [exerciseArray release];
    [selectedSession release];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(IBAction)showActionSheet {
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Share" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Twitter",@"Facebook",nil];
    [actionSheet showInView:self.tabBarController.view];
    [actionSheet release];
}

- (void)tweet
{
    SHKItem *aTweet = [SHKItem text:[NSString stringWithFormat: @"Twitter: testing 1,2,3."]];
    [SHKTwitter shareItem:aTweet];
}

- (void)facebook
{
    SHKItem *post = [SHKItem text: [NSString stringWithFormat: @"Facebook: testing 1,2,3."]];
//    post.URL = [NSURL URLWithString:@"http://sugarrush-app.com/"];
    [SHKFacebook shareItem:post];
} 

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIBarButtonItem *actionButton = [[UIBarButtonItem alloc] initWithTitle:@"Share" style:UIBarButtonItemStylePlain target:self action:@selector(showActionSheet)];
    self.navigationItem.rightBarButtonItem = actionButton;
    [actionButton release];

    NSSet *exercises = [self.selectedSession valueForKey:@"exercises"];
    NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"timeStamp" ascending:YES]];
    NSArray *sorted = [exercises sortedArrayUsingDescriptors:sortDescriptors];
    self.exerciseArray = sorted;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [exerciseArray count];
}

- (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];
    }
    Exercise *exercise = (Exercise *)[exerciseArray objectAtIndex:indexPath.row];
    cell.textLabel.text = exercise.name;
    return cell;
}

@end
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
  • 2
    Where do you allocate `selectedSession` in the first place? – Chris Frederick May 31 '11 at 22:28
  • By the way, [this question](http://stackoverflow.com/questions/1210776/objective-c-difference-between-setting-nil-and-releasing) provides some more information that may be helpful to you. – Chris Frederick May 31 '11 at 22:34
  • Is it possible that your `__fetchedResultsController` is releasing `selectedSession`, too? That could definitely be a problem. – Chris Frederick May 31 '11 at 22:50
  • Where are you setting __fetchedResultsController for each of these view controllers? – Firoze Lafeer May 31 '11 at 23:23
  • That is just the way the apple template had the code setup. I can do without it. –  May 31 '11 at 23:24
  • I've changed it all to just fetchedResultsController. –  May 31 '11 at 23:29
  • Didn't really answer the question. :) Where are you setting the fetchedResultsController for each of these view controllers? – Firoze Lafeer May 31 '11 at 23:33
  • Oh sorry I thought you asked why. Ok I didnt post te fetch methods or delegate method but I will include them now. –  May 31 '11 at 23:43
  • I've added the fetch code to each viewcontroller. –  Jun 01 '11 at 00:04
  • The crash only happens after viewing SessionViewController, so I think its something in that class, not in the fetch methods of the other classes. –  Jun 01 '11 at 00:14
  • @Faisal, that's not a good assumption. The bug could very easily be earlier than that. That's pretty common with memory management bugs. – Firoze Lafeer Jun 01 '11 at 00:57
  • I think I got it, when setting `selectedSession` in `LogResultsViewController's `didSelectRowAtIndexMethod`, I now used `self.selectedSession = (Session *)[fetchedResultsController objectAtIndexPath:indexPath];` instead of `selectedSession = (Session *)[fetchedResultsController objectAtIndexPath:indexPath];` –  Jun 01 '11 at 01:01

4 Answers4

3

The only objects you should be releasing or setting to nil in viewDidUnload are like buttons, labels, textBoxes etc.

When you do self.selectedSession = nil, for example, it is calling the release for that method; that is the point of properties, they handle the allocs and releases.

RyanG
  • 4,393
  • 2
  • 39
  • 64
  • This should not cause the crash though. Sending messages to nil just doesn't do anything. Is the name of the instance variable selectedSession too? – Sascha May 31 '11 at 22:33
  • @Sascha I was having similar problems recently, I had all my arrays and dictionaries being set to nil in the viewDidUnload method and once I removed them I stopped getting the deallocated instance error. – RyanG May 31 '11 at 22:36
0

in your viewDidLoad method you are setting self.selectedSession and self.exerciseArray to nil. You should only set interface outlets to nil in viewDidLoad. But this isn't the cause of your crash because by the time you get to dealloc, you are just sending release to nil.

you might want to look into the contents of the selectedSession Object. you might be over releasing an NSString in one of it's members

timthetoolman
  • 4,613
  • 1
  • 22
  • 22
0

Dont set selectedSession and exerciseArray to nil in viewDidUnload.

Since you're doing that, it will crash in the dealloc as you're trying to release nil objects.

Also, before you release arrays, it's always a good idea to call [array removeAllObjects].

Sid
  • 9,508
  • 5
  • 39
  • 60
  • 2
    You can't crash trying to send release to nil. Nothing (good or bad) will happen from that. – Firoze Lafeer May 31 '11 at 22:30
  • Both of the points here are just wrong. As Firoze points out, there's no harm in messaging `nil`, and there's no reason to call `-removeAllObjects` -- they'll be released when the array is destroyed. What if some other code is using that array? – Seamus Campbell May 31 '11 at 23:11
  • No need to apologize! Geez, we're not doing surgery or something. :) – Firoze Lafeer May 31 '11 at 23:35
0

You posted a tableView:didSelectRowAtIndexPath:, but I don't think you told us which class that was in.

In any case, that method seems to have a bug:

selectedSession = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
sessionViewController.selectedSession = self.selectedSession;

I think on the first line, you meant to say self.selectedSession, assuming you go on to release selectedSession in this class' dealloc. (This may not be your only issue)

EDIT:

You should set properties to nil in viewDidUnload if and only if those properties were set as a result of the loading of the view from your nib, or were set in loadView, or in viewDidLoad. The reason you're doing this is because viewDidLoad or loadView may be called more than once during the lifetime of the view controller.

EDIT:

Check that you are using the property when setting fetchedResultsController and make sure you aren't setting that to nil on viewDidUnload.

Firoze Lafeer
  • 17,133
  • 4
  • 54
  • 48
  • thanks i fixed that. I am currently getting an EXC BAD ACCESS error in LogResultsViewController in method `- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath` at line `Session *session = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];` –  May 31 '11 at 22:54
  • Pls post your updated code with any fixes you may have made since you opened this question. – Firoze Lafeer May 31 '11 at 22:55
  • Also, now you may have the issue that others have been pointing out, which is you are releasing things in viewDidUnload that don't appear to make sense. (like your fetchedResultsController for example) – Firoze Lafeer May 31 '11 at 23:00
  • Oh ok, i thought `fetchedResultsController` was supposed to be in `viewDidUnload`. Should I remove it then from all the classes? What else should I remove from `viewDidUnload`? –  May 31 '11 at 23:02
  • Also, when you update the code, can you update the error also with the line where it occurs with the current code. – Firoze Lafeer May 31 '11 at 23:02
  • Currently, it is just crashing in main.m at `int retVal = UIApplicationMain(argc, argv, nil, nil);` with `EXC_BAD_ACCESS` –  May 31 '11 at 23:05
  • I updated my answer to address your question about viewDidUnload – Firoze Lafeer May 31 '11 at 23:05
  • Sounds like it's time to break out NSZombie then. – Firoze Lafeer May 31 '11 at 23:07
  • Ok, this time I got `*** -[CFString release]: message sent to deallocated instance 0x5d212e0` again at dealloc's `[selectedSession release];` in SessionViewControler. –  May 31 '11 at 23:11
  • Do you know how to look at the history of a zombie? – Firoze Lafeer May 31 '11 at 23:18
  • No, I don't. Should I do that? –  May 31 '11 at 23:19