UInavigationbar和super dealloc导致应用程序崩溃

时间:2012-07-16 14:28:37

标签: objective-c ios ios5

当我在UINavigation中使用后退按钮时,我正在应用程序崩溃,并且孩子[supper dealloc]称为应用程序崩溃。我试过,但我找不到任何错误。仪器说下面的问题,但我没有明白这一点

#   Address Category    Event Type  RefCt   Timestamp   Size    Responsible Library Responsible Caller
0   0x9e8c8c0   CALayer Malloc  1   00:05.082.180   48  UIKit   -[UIView _createLayerWithFrame:]
1   0x9e8c8c0   CALayer Zombie  -1  00:18.855.037   0   QuartzCore  CA::release_objects(X::List<void const*>*)

如果你能帮助我,我将非常感谢你。

这是根页面代码

//
//  TNTScenarioViewController.m
//  TurfNutritionTool
//
//  Created by Aashish Joshi on 10/20/11.
//  Copyright 2011 Abacus Consultancy Services. All rights reserved.
//

#import "TNTScenarioViewController.h"
#import "ScenarioDetailViewController.h"
#import <QuartzCore/QuartzCore.h>

@implementation TNTScenarioViewController

@synthesize scenarioTable =             _scenarioTable;
@synthesize scenarioDetail =            _scenarioDetail;
@synthesize scenarioId =                _scenarioId;
@synthesize scenarioTableCellStyle =    _scenarioTableCellStyle;
@synthesize dbObject =                  _dbObject;
@synthesize headerDateLabel =           _headerDateLabel;
@synthesize headerTurfAcresLabel =      _headerTurfAcresLabel;
@synthesize headerScenarioIDLabel =     _headerScenarioIDLabel;
@synthesize headerDescriptionLabel =    _headerDescriptionLabel;
@synthesize headerProductTypeLabel =    _headerProductTypeLabel;
@synthesize headerTargetNitrogenLabel = _headerTargetNitrogenLabel;
@synthesize headerView =                _headerView;
@synthesize synchronize =               _synchronize;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (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.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    UIColor *_background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"main_login_bg.png"]];
    self.view.backgroundColor = _background;
    [_background release];

    _scenarioTable.delegate = self;
    _scenarioTable.dataSource = self;

    // Set the table view to be rounded
    [[self.scenarioTable layer] setCornerRadius:5.0];

    [self loadDBAccessDatabase];
    // [self didApplicationLaunchedFirstTime];

    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    UIToolbar* _rightNavBarTools = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 260, 44)];

    // create the array to hold the buttons, which then gets added to the toolbar
    NSMutableArray* _rightNavBarButtons = [[NSMutableArray alloc] initWithCapacity:4];

    UIBarButtonItem *_signout = [[UIBarButtonItem alloc] initWithTitle:@"Sign out" style:UIBarButtonItemStyleBordered target:self action:@selector(didApplicationLaunchedFirstTime)];
    [_rightNavBarButtons addObject:_signout];

    [_signout release];

    UIBarButtonItem *_syncronize = [[UIBarButtonItem alloc] initWithTitle:@"Synchronize" style:UIBarButtonItemStyleBordered target:self action:@selector(syncronize)];
    [_rightNavBarButtons addObject:_syncronize];
    [_syncronize release];

    UIBarButtonItem *_addNewScenario = [[UIBarButtonItem alloc] 
                                        initWithTitle:@"New TNT" style:UIBarButtonItemStyleBordered target:self 
                                        action:@selector(startNewScenario)];
    [_rightNavBarButtons addObject:_addNewScenario];
    [_addNewScenario release];

    [_rightNavBarTools setItems:_rightNavBarButtons animated:NO];
    [_rightNavBarButtons release];

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:_rightNavBarTools] autorelease];
    [_rightNavBarTools release];

    [self loadAllScenario];
}

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"%d", [self retainCount]);
    [super viewWillAppear:animated];
    [self loadAllScenario];
    [self.scenarioTable reloadData];
}

- (void)viewDidUnload
{
    [_scenarioTable release];
    [_scenarioDetail release];
    [_scenarioId release];
    [_scenarioTableCellStyle release];

    self.scenarioTable = nil;
    self.scenarioDetail = nil;
    self.scenarioId = nil;
    self.scenarioTableCellStyle = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

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

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [self.scenarioId count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        [[NSBundle mainBundle] loadNibNamed:@"scenarioTableCellStyle" owner:self options:nil];
        cell = self.scenarioTableCellStyle;
        self.scenarioTableCellStyle = nil;
    }

    if (indexPath.row % 2 == 0) {
        cell.contentView.backgroundColor = [UIColor colorWithWhite:253.0/255 alpha:1];
    } else {
        cell.contentView.backgroundColor = [UIColor colorWithWhite:250.0/255 alpha:1];
    }


    NSDictionary * _scenarioDetailRow = [self.dbObject getScenarioDetail:[self.scenarioId objectAtIndex:indexPath.row]];

    NSNumber* _tempNumber;
    NSNumberFormatter* _formatter = [[NSNumberFormatter alloc] init];
    NSString* _convertedNumber;

    // Configure the cell...
    _tempNumber = [_scenarioDetailRow objectForKey:@"scenarioid"];
    [_formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    _convertedNumber = [_formatter stringForObjectValue:_tempNumber];

    UILabel* _label = (UILabel *)[cell viewWithTag:1];
    _label.text = _convertedNumber;

    _label = (UILabel *)[cell viewWithTag:2];
    NSString* _turftype = [_scenarioDetailRow objectForKey:@"turf"];
    _label.text = _turftype;

    _label = (UILabel *)[cell viewWithTag:3];
    _tempNumber = [_scenarioDetailRow objectForKey:@"targetnitrogen"];
    [_formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    _convertedNumber = [_formatter stringForObjectValue:_tempNumber];
    _label.text = _convertedNumber;

    _label = (UILabel *)[cell viewWithTag:4];
    _tempNumber = [_scenarioDetailRow objectForKey:@"turfacre"];
    [_formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    _convertedNumber = [_formatter stringForObjectValue:_tempNumber];
    _label.text = _convertedNumber;
    [_formatter release];

    _label = (UILabel *)[cell viewWithTag:5];
    NSString* _dateCreated = [_scenarioDetailRow objectForKey:@"datecreated"];

    NSDateFormatter *inputFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [inputFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

    NSDate *_inputDateCreated = [inputFormatter dateFromString:_dateCreated];
    NSDateFormatter *outputFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [outputFormatter setDateFormat:@"MM-dd-yyyy"];

    NSString *_outputDateCreated = [outputFormatter stringFromDate:_inputDateCreated];

    _label.text = _outputDateCreated;

    _label = (UILabel *)[cell viewWithTag:6];

    if (([_scenarioDetailRow objectForKey:@"description"] != nil) && ([_scenarioDetailRow objectForKey:@"description"] != (id)[NSNull null])){

        NSString* _discription = [_scenarioDetailRow objectForKey:@"description"];
        _label.text = _discription;

    } else {

        _label.text = [NSString stringWithString:@""];
    }

    return cell;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    if (UIInterfaceOrientationIsLandscape(fromInterfaceOrientation))
    {
        // Move the plots into place for portrait
        _headerScenarioIDLabel.frame        = CGRectMake(-30, 2, 125, 20);
        _headerDescriptionLabel.frame       = CGRectMake(52, 2, 125, 20);
        _headerProductTypeLabel.frame       = CGRectMake(278, 2, 125, 20);
        _headerTargetNitrogenLabel.frame    = CGRectMake(368, 2, 125, 20);
        _headerTurfAcresLabel.frame         = CGRectMake(437, 2, 125, 20);
        _headerDateLabel.frame              = CGRectMake(545, 2, 125, 20);
    }
    else
    {
        // Move the plots into place for landscape
        _headerScenarioIDLabel.frame        = CGRectMake(-26, 2, 125, 20);
        _headerDescriptionLabel.frame       = CGRectMake(85, 2, 125, 20);
        _headerProductTypeLabel.frame       = CGRectMake(390, 2, 125, 20);
        _headerTargetNitrogenLabel.frame    = CGRectMake(526, 2, 125, 20);
        _headerTurfAcresLabel.frame         = CGRectMake(626, 2, 125, 20);
        _headerDateLabel.frame              = CGRectMake(759, 2, 125, 20);

    }
}


- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 

    _headerScenarioIDLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
    _headerDateLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
    _headerDescriptionLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
    _headerProductTypeLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
    _headerTargetNitrogenLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
    _headerTurfAcresLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;    
    BOOL isLandscape = UIDeviceOrientationIsLandscape(self.interfaceOrientation);

    if (UIInterfaceOrientationIsLandscape(orientation) || isLandscape)

    {
        // Move the plots into place for landscape
        _headerScenarioIDLabel.frame        = CGRectMake(-26, 2, 125, 20);
        _headerDescriptionLabel.frame       = CGRectMake(85, 2, 125, 20);
        _headerProductTypeLabel.frame       = CGRectMake(390, 2, 125, 20);
        _headerTargetNitrogenLabel.frame    = CGRectMake(526, 2, 125, 20);
        _headerTurfAcresLabel.frame         = CGRectMake(626, 2, 125, 20);
        _headerDateLabel.frame              = CGRectMake(759, 2, 125, 20);
    }

    else
    {
        // Move the plots into place for portrait
        _headerScenarioIDLabel.frame        = CGRectMake(-30, 2, 125, 20);
        _headerDescriptionLabel.frame       = CGRectMake(52, 2, 125, 20);
        _headerProductTypeLabel.frame       = CGRectMake(278, 2, 125, 20);
        _headerTargetNitrogenLabel.frame    = CGRectMake(368, 2, 125, 20);
        _headerTurfAcresLabel.frame         = CGRectMake(437, 2, 125, 20);
        _headerDateLabel.frame              = CGRectMake(545, 2, 125, 20);
    }

    if(_headerView == nil) {
        //allocate the view if it doesn't exist yet
        _headerView  = [[UIView alloc] init];

        UIColor *_background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"toolbar_bkg.png"]];
        _headerView.backgroundColor = _background;
        [_background release];


        _headerScenarioIDLabel.backgroundColor = [UIColor clearColor];
        _headerScenarioIDLabel.opaque = NO;
        _headerScenarioIDLabel.textColor = [UIColor whiteColor];
        _headerScenarioIDLabel.font = [UIFont boldSystemFontOfSize:12];
        _headerScenarioIDLabel.textAlignment = UITextAlignmentCenter;
        _headerScenarioIDLabel.text = @"ID";


        _headerDateLabel.backgroundColor = [UIColor clearColor];
        _headerDateLabel.opaque = NO;
        _headerDateLabel.textColor = [UIColor whiteColor];
        _headerDateLabel.font = [UIFont boldSystemFontOfSize:12];
        _headerDateLabel.textAlignment = UITextAlignmentCenter;
        _headerDateLabel.text = @"Date";


        _headerDescriptionLabel.backgroundColor = [UIColor clearColor];
        _headerDescriptionLabel.opaque = NO;
        _headerDescriptionLabel.textColor = [UIColor whiteColor];
        _headerDescriptionLabel.font = [UIFont boldSystemFontOfSize:12];
        _headerDescriptionLabel.textAlignment = UITextAlignmentCenter;
        _headerDescriptionLabel.text = @"Description";


        _headerProductTypeLabel.backgroundColor = [UIColor clearColor];
        _headerProductTypeLabel.opaque = NO;
        _headerProductTypeLabel.textColor = [UIColor whiteColor];
        _headerProductTypeLabel.font = [UIFont boldSystemFontOfSize:12];
        _headerProductTypeLabel.textAlignment = UITextAlignmentCenter;
        _headerProductTypeLabel.text = @"Product Type";


        _headerTargetNitrogenLabel.backgroundColor = [UIColor clearColor];
        _headerTargetNitrogenLabel.opaque = NO;
        _headerTargetNitrogenLabel.textColor = [UIColor whiteColor];
        _headerTargetNitrogenLabel.font = [UIFont boldSystemFontOfSize:12];
        _headerTargetNitrogenLabel.textAlignment = UITextAlignmentCenter;
        _headerTargetNitrogenLabel.text = @"Target N";


        _headerTurfAcresLabel.backgroundColor = [UIColor clearColor];
        _headerTurfAcresLabel.opaque = NO;
        _headerTurfAcresLabel.textColor = [UIColor whiteColor];
        _headerTurfAcresLabel.font = [UIFont boldSystemFontOfSize:12];
        _headerTurfAcresLabel.textAlignment = UITextAlignmentCenter;
        _headerTurfAcresLabel.text = @"Turf Acres";

        //add the button to the view
        [_headerView addSubview:_headerScenarioIDLabel];
        [_headerView addSubview:_headerDescriptionLabel];
        [_headerView addSubview:_headerProductTypeLabel];
        [_headerView addSubview:_headerTargetNitrogenLabel];
        [_headerView addSubview:_headerTurfAcresLabel];
        [_headerView addSubview:_headerDateLabel];

    }

    //return the view for the footer
    return _headerView;
}
// specify the height of your footer section
- (CGFloat)tableView:(UITableView *)tableView
heightForHeaderInSection:(NSInteger)section {
    //differ between your sections or if you
    //have only on section return a static value
    return 24;
}

- (CGFloat)tableView:(UITableView *)tableView
heightForFooterInSection:(NSInteger)section {
    //differ between your sections or if you
    //have only on section return a static value
    return 14;
}

- (UIView *) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 

    UIColor *_background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"toolbar_bkg.png"]];
    UIView* _customView = [[[UIView alloc]initWithFrame:CGRectMake(10.0, 0.0, 300.0, 44.0)]autorelease];
    _customView.backgroundColor = _background;
    [_background release];
    return _customView; 
}


/*
 // 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
 [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
 }   
 }
 */

/*
 // Override to support rearranging the table view.
 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
 {
 }
 */

/*
 // Override to support conditional rearranging of the table view.
 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
 {
 // Return NO if you do not want the item to be re-orderable.
 return YES;
 }
 */

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.

     ScenarioDetailViewController* _detailViewController = [[ScenarioDetailViewController alloc] initWithNibName:@"ScenarioDetailViewController" bundle:nil];
     _detailViewController.dbObject = self.dbObject;
     [_detailViewController setScenarioId:[self.scenarioId objectAtIndex:indexPath.row]];
     [self.navigationController pushViewController:_detailViewController animated:YES];
    [_detailViewController release];
}

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    // Updates the appearance of the Edit|Done button as necessary.
    [super setEditing:editing animated:animated];
    [self.scenarioTable setEditing:editing animated:YES];
    // Disable the add button while editing.
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // must update the database before updating the tableView
        // so that the tableView never has a row that's missing from the database
        [self.dbObject deleteScenarioRow:[self.scenarioId objectAtIndex:indexPath.row]];
        [self loadAllScenario];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                         withRowAnimation:UITableViewRowAnimationFade];
        [self.scenarioTable reloadData];
    }   
}

- (void)dealloc {

    [_synchronize release];    
    [_scenarioTable release];
    [_scenarioDetail release];
    [_scenarioId release];
    [_scenarioTableCellStyle release];
    [_headerDateLabel release];
    [_headerTurfAcresLabel release];
    [_headerScenarioIDLabel release];
    [_headerDescriptionLabel release];
    [_headerProductTypeLabel release];
    [_headerTargetNitrogenLabel release];
    [_headerView release];
    [super dealloc];
}

// Called when an alertview button is touched
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

    switch (buttonIndex) {
        case 0: 
        {       
            NSLog(@"user not want to sync");
        }
            break;

        case 1: 
        {
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

            _synchronize = [[TNSynchronize alloc] init];
            _synchronize.delegate = self;
            [_synchronize jesonRequest];

            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        }   
            break;
    }
}

- (void) reloadAfterSyncronize {

    [self loadAllScenario];
    [self.scenarioTable reloadData];
}

#pragma mark - TNTScenarioViewController lifecycle methods

- (void) syncronize {

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Syncronize process", nil)
                                                    message:NSLocalizedString(@"\n Syncronize process will be start and work in background.", nil)
                                                   delegate:self 
                                          cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
                                          otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
    [alert show];
    [alert release];
}

- (void) didApplicationLaunchedFirstTime {

    LoginViewController *loginViewObj = [[[LoginViewController alloc] init] autorelease];
    loginViewObj.dbObject = self.dbObject;

    UINavigationController *navigationController = [[[UINavigationController alloc]
                                                     initWithRootViewController:loginViewObj] autorelease];

    navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentModalViewController:navigationController animated:YES];
} 


- (void)loadSynchronizeController {

    [self.scenarioTable reloadData];
}

// This is Method to New Scenario
- (void) startNewScenario {

    ScenarioDetailViewController* _detailViewController = [[ScenarioDetailViewController alloc] initWithNibName:@"ScenarioDetailViewController" bundle:nil];
    [_detailViewController setScenarioId:[NSNumber numberWithInt:0]];
    [self.navigationController pushViewController:_detailViewController animated:YES];
    // [_detailViewController release];
}

// This Method use for Load Value of Scenario
- (NSMutableArray *) loadAllScenario {
    // NSLog(@"%s", __FUNCTION__);

    // First, test for existence.
    NSArray* _paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* _documentsDirectory = [_paths objectAtIndex:0];
    NSString* _writableConfigPath = [_documentsDirectory stringByAppendingPathComponent:@"Configuration.plist"];
    NSMutableDictionary* _configFile = [[NSMutableDictionary alloc] initWithContentsOfFile:_writableConfigPath];

    NSString* _loginStatus= [NSString stringWithString:[_configFile objectForKey:@"UserEmail"]];
    [_configFile autorelease];

    [self.scenarioId removeAllObjects];

    if (!_dbObject) [self loadDBAccessDatabase];
    self.scenarioId = [NSMutableArray arrayWithArray:[_dbObject getRelatedScenarioArray:_loginStatus]];

    return self.scenarioId;
}

- (NSArray *) loadScenarioIDsIfEmpty {
    // NSLog(@"%s", __FUNCTION__);

    // First, test for existence.
    NSArray* _paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* _documentsDirectory = [_paths objectAtIndex:0];
    NSString* _writableConfigPath = [_documentsDirectory stringByAppendingPathComponent:@"Configuration.plist"];
    NSMutableDictionary* _configFile = [[NSMutableDictionary alloc] initWithContentsOfFile:_writableConfigPath];

    NSString* _loginStatus = [NSString stringWithString:[_configFile objectForKey:@"UserEmail"]];
    [_configFile autorelease];

    if (!_dbObject) [self loadDBAccessDatabase];
    if (!self.scenarioId || ![self.scenarioId count]) self.scenarioId = [NSMutableArray arrayWithArray:[_dbObject getRelatedScenarioArray:_loginStatus]];
    return self.scenarioId;
}

- (DBAccess *) loadDBAccessDatabase {
    // NSLog(@"%s", __FUNCTION__);

    _dbObject = [DBAccess sharedDBObjectAccess];
    return _dbObject;
}

@end

这是您提出的dealloc方法

- (void)dealloc {

    [_scenarioProductTable release];
    [_attributePopover release];
    [_gotMapRegion release];
    [_gotTargetN release];
    [_gotTurfAcres release];
    [_gotTurftype release];
    [_scenarioId release];
    [_granularProductData release]; 
    [_liquidProductData release];
    [_areaGraphData release];
    [_scenarioAppId release];
    [_scenarioProductTableCellStyle release];
    [_scenarioProductTable release];
    [_carryOver release];
    [_tempDiscription release];
    [_scenarioDetailRow release];
    [_turfacresTextField release];
    [_discriptionTextField release];
    [_footerView release];
    [_headerView release];
    [selectedTurftypeLabel release];
    [selectedTargetNLabel release];
    [selectedMapregionLabel release];
    [selectedTurfAcresLabel release];
    [_loginUser release];
    [super dealloc];
}

并且在这个函数中它说我有问题

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.

     ScenarioDetailViewController* _detailViewController = [[ScenarioDetailViewController alloc] initWithNibName:@"ScenarioDetailViewController" bundle:nil];
     _detailViewController.dbObject = self.dbObject;
     [_detailViewController setScenarioId:[self.scenarioId objectAtIndex:indexPath.row]];
     [self.navigationController pushViewController:_detailViewController animated:YES];
    [_detailViewController release];
}

这条线在功能上有100%的责任

[self.navigationController pushViewController:_detailViewController animated:YES];

3 个答案:

答案 0 :(得分:2)

从崩溃报告中可以看出,你正在过度释放一个对象(注意它说僵尸CALayer的保留计数为-1;任何小于0的东西都被过度释放)。我的建议是在您找到它之前搜索您的代码,使用“工具”工具“Zombies”(仅在模拟器上进行概要分析时),或者将项目升级到ARC。

我肯定会建议升级到ARC作为最佳选择。 ARC简化了您的代码并降低了峰值内存占用,提高了效率并大大降低了崩溃的可能性。

编辑:

升级到ARC :(来自Xcode菜单)

Edit -> Refactor -> Convert to Objective-C ARC...

(来自Apple的人脸检测示例项目)

enter image description here

编辑2:

回应@Chris的回答:

在viewDidUnload中,您应该只释放在viewDidLoad中创建的对象;此外,您通常只应将IBOutlets设置为零。每次调用viewDidUnload时,都会调用viewDidLoad来重新创建viewDidUnload中销毁的所有内容。因此,在viewDidUnload中,该课程为,只有在viewDidLoad 中创建的对象为nil。如果您发布了未在viewDidLoad中创建的内容,则返回到该视图时将不会重新创建,这可能会导致崩溃。

但我不认为这是你的问题。视图控制器被销毁时实际上不会调用viewDidUnload(因为控制器是从导航堆栈弹出或模态视图控制器被解除而调用dealloc)。 viewDidUnload仅在应用程序收到内存警告时调用 - viewDidUnload的作用是释放可以在以后重新创建的任何对象。假设您没有收到任何内存警告,并且您只是从堆栈中推送/弹出视图控制器,则双重释放是viewDidUnload不会导致 问题(尽管它可能会导致一个人。)

故事的道德:

使用ARC。它不是玩具,它确实有效。它不会“减少”你对内存管理的控制 - 它不再需要它。除了保留周期(Brad Larson在这里给出了一个很好的解释:What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?),ARC将负责几乎所有的内存管理,特别是泄漏。您仍然可以使用以下方法删除对象:

someObject = nil;

因此您仍然可以控制内存占用。 @autoreleasepools仍然是ARC的一个选项。

所以,故事的最终道德:

使用ARC。

答案 1 :(得分:1)

- (void)viewDidUnload
{
    [_scenarioTable release];
    [_scenarioDetail release];
    [_scenarioId release];
    [_scenarioTableCellStyle release];

    self.scenarioTable = nil;
    self.scenarioDetail = nil;
    self.scenarioId = nil;
    self.scenarioTableCellStyle = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

您的-viewDidUnload方法是双重释放。首先,通过引用它们的实例变量来显式release个对象,即:[_scenarioTable release];。但是在执行此操作后,您不会将ivar设置为nil。所以这些实例变量仍然指向已发布的对象。

然后将这些实例变量支持的属性设置为nil。可能使用retain内存管理策略声明属性。这意味着当您执行self.scenarioTable = nil;时,它将release与该财产相关联的ivar。

要解决此问题,只需摆脱顶部的4个release来电。

- (void)viewDidUnload
{
    self.scenarioTable = nil;
    self.scenarioDetail = nil;
    self.scenarioId = nil;
    self.scenarioTableCellStyle = nil;
    [super viewDidUnload];
}

如果您真的想保留它们,请将其更改为:

- (void)viewDidUnload
{
    [_scenarioTable release]; _scenarioTable = nil;
    [_scenarioDetail release]; _scenarioDetail = nil;
    [_scenarioId release]; _scenarioId = nil;
    [_scenarioTableCellStyle release]; _scenarioTableCellStyle = nil;
    [super viewDidUnload];
}

这就是iOS 6中不推荐使用-viewDidUnload的原因。

答案 2 :(得分:0)

像Rickay说的那样,在你的dealloc方法中,你的viewDidUnload将你的4个场景对象释放两次。我只使用ARC,但我很确定这是你的问题