对象被解除分配不知道为什么?

时间:2011-12-23 14:26:56

标签: objective-c ios

请帮助我,我无法理解为什么会发生这种情况,_getProductType对象无需任何理由解除分配。请看看,我无法弄清楚发生了什么,如果你可以帮助我,我将非常感谢你,提前致谢

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

    #import "ProductComponentViewController.h"
    #import <QuartzCore/QuartzCore.h>

    @implementation ProductComponentViewController

    @synthesize productTableView =      _productTableView;
    @synthesize productTypeSelector =   _productTypeSelector;
    @synthesize turftypePopover =       _turftypePopover;
    @synthesize gotTurftype =           _gotTurftype;
    @synthesize resultProduct =         _resultProduct;
    @synthesize productTableCellStyle = _productTableCellStyle;
    @synthesize dbObject =              _dbObject;
    @synthesize getProductType =        _getProductType;

    #define Granular @"G"
    #define Liquid @"L"
    #define Tankmix @"T"
    #define AllProduct @"A"

    - (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];
        // D    o any additional setup after loading the view from its nib.

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

        // init the segment button value 
        [productTypeSelector setSelectedSegmentIndex:0];

        _getProductType = [[NSString alloc] initWithString:AllProduct];

        // set table delegate
        _productTableView.delegate = self;

        // load the product
        [self loadProductComponentValues];

        // Set the table view to be rounded
        [[_productTableView layer] setCornerRadius:5.0];
    }

    - (void)viewDidUnload
    {
        [self setProductTableView:nil];
        [self setProductTypeSelector:nil];

        _productTableView = nil;
        _productTypeSelector = nil;
        _turftypePopover = nil;
        _gotTurftype = nil;
        _resultProduct = nil;
        _productTableCellStyle = nil;
        _getProductType = nil;

        [_getProductType release];
        [_productTableView release];
        [_productTypeSelector release];
        [_turftypePopover release];
        [_gotTurftype release];
        [_resultProduct release];
        [_productTableCellStyle release];

        [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;
    }

    - (void)dealloc {

        [_getProductType release];
        [_productTableView release];
        [_productTypeSelector release];
        [_turftypePopover release];
        [_gotTurftype release];
        [_resultProduct release];
        [_productTableCellStyle release];    

        [super dealloc];
    }

    #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.

    // NSLog(@"%s", __FUNCTION__);
    return [self.resultProduct count];
}

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

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


    NSDictionary * _productRow = [_dbObject getProductdetail:[self.resultProduct objectAtIndex:indexPath.row]];


    // Configure the cell...

    UILabel* _label = (UILabel *)[cell viewWithTag:1];
    NSString* _linkcode = [_productRow objectForKey:@"linkcode"];  
    _label.text = _linkcode;

    _label = (UILabel *)[cell viewWithTag:2];
    NSString* _description = [_productRow objectForKey:@"description"];
    _label.text = _description;

    _label = (UILabel *)[cell viewWithTag:3];
    NSString* _productcode = [_productRow objectForKey:@"productcode"];
    _label.text = _productcode;

    _label = (UILabel *)[cell viewWithTag:4];
    NSString* _weight = [_productRow objectForKey:@"weight"];
    _label.text = _weight;

    _label = (UILabel *)[cell viewWithTag:6];
     NSNumber* _costperBag = [[NSNumber alloc] initWithFloat:[[_dbObject getUserProductCost:[self.resultProduct objectAtIndex:indexPath.row]] floatValue]];
    _label.text = [@"$ " stringByAppendingString:[_costperBag stringValue]];
    [_costperBag autorelease];


    _getProductType = [_productRow objectForKey:@"producttype"];

    if ([_getProductType isEqualToString:@"G"]) {

        _label = (UILabel *)[cell viewWithTag:10];
        NSString* _weightTag = [[NSString alloc] initWithString:@"Weight in Lbs"];  
        _label.text = _weightTag;
        [_weightTag autorelease];

        _label = (UILabel *)[cell viewWithTag:11];
        NSString* _SGNTag = [[NSString alloc] initWithString:@"SGN"];  
        _label.text = _SGNTag;
        [_SGNTag autorelease];

        _label = (UILabel *)[cell viewWithTag:5];
        NSString* _sgn = [_productRow objectForKey:@"sgn"];
        _label.text = _sgn;

} else if([_getProductType isEqualToString:@"L"]) {

        _label = (UILabel *)[cell viewWithTag:10];
        NSString* _weightTag = [[NSString alloc] initWithString:@"Weight in Ozs"];  
        _label.text = _weightTag;
        [_weightTag autorelease];

        _label = (UILabel *)[cell viewWithTag:11];
        NSString* _SGTag = [[NSString alloc] initWithString:@"SG"];
        _label.text = _SGTag;
        [_SGTag autorelease];


        _label = (UILabel *)[cell viewWithTag:5];
        NSString* _sgn = [_productRow objectForKey:@"sg"];
        _label.text = _sgn;

    } else if([_getProductType isEqualToString:@"T"]) {

         _label = (UILabel *)[cell viewWithTag:10];
         NSString* _weightTag = [[NSString alloc] initWithString:@"Weight in Ozs"];  
        _label.text = _weightTag;
        [_weightTag autorelease];

        _label = (UILabel *)[cell viewWithTag:11];
         NSString* _SGTag = [[NSString alloc] initWithString:@"SG"];
        _label.text = _SGTag;
        [_SGTag autorelease];    

        _label = (UILabel *)[cell viewWithTag:5];
        NSString* _sgn = [_productRow objectForKey:@"sg "];
        _label.text = _sgn;
    }
    return cell;
}

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

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

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

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     [detailViewController release];

    if (_delegate != nil) {
        NSString *_selectedTurftype = [_getTurftype objectAtIndex:indexPath.row];
        [_delegate getSelectedTurftype:_selectedTurftype];
    }
     */
    // NSDictionary * _productRow = [_dbObject getProductdetail:[self.resultProduct objectAtIndex:indexPath.row]];

    // Animate the deselection
    [self.productTableView deselectRowAtIndexPath:[self.productTableView indexPathForSelectedRow] animated:YES];

    CGRect _popoverRect = CGRectMake(800.0f, 380.0f, 10.0f, 10.0f);

    if ([_turftypePopover isPopoverVisible]) {
        [_turftypePopover dismissPopoverAnimated:YES];
    }
    else
    {
        ProductDetailViewController* _productDetailViewControllerObj = [[ProductDetailViewController alloc] init];
        _turftypePopover = [[UIPopoverController alloc]
                            initWithContentViewController:_productDetailViewControllerObj];
        _productDetailViewControllerObj.dbObject = _dbObject;

        [_productDetailViewControllerObj getSelectedProductId:[self.resultProduct objectAtIndex:indexPath.row] ];
        [_productDetailViewControllerObj release];
        _turftypePopover.popoverContentSize = CGSizeMake(360, 500);
        [_turftypePopover presentPopoverFromRect:_popoverRect inView:self.view 
                        permittedArrowDirections:0 animated:YES];
    }

    [self.productTableView deselectRowAtIndexPath:[self.productTableView indexPathForSelectedRow] animated:YES];
}

#pragma mark - ProductComponentViewController lifecycle methods

- (IBAction)laodTurftype:(id)sender {

    [self initAllTheProduct];

    if (_getProductType == (id)[NSNull null] && _getProductType == nil) {

        _getProductType = [NSString stringWithString:AllProduct];
    }

    if ([_turftypePopover isPopoverVisible]) {
        [_turftypePopover dismissPopoverAnimated:YES];
    }
    else
    {
        TurftypePopoverViewController* _turftypeControllerObj = [[TurftypePopoverViewController alloc] init];

        _turftypeControllerObj.dbObject = _dbObject;

        _turftypeControllerObj.delegate = self;

        _turftypePopover = [[UIPopoverController alloc]
                            initWithContentViewController:_turftypeControllerObj];
        [_turftypeControllerObj release];

        _turftypePopover.popoverContentSize = CGSizeMake(150, 225);
        [_turftypePopover presentPopoverFromBarButtonItem:sender
                                 permittedArrowDirections:UIPopoverArrowDirectionAny
                                                 animated:YES];
    }
}

- (IBAction)setProductType:(id)sender {

     switch (_productTypeSelector.selectedSegmentIndex) {
         case 0:
             _getProductType =  [NSString stringWithString:AllProduct];
             break;
         case 1:
             _getProductType = [NSString stringWithString:Granular];
             break;   
         case 2:
             _getProductType = [NSString stringWithString:Liquid];
             break; 
         case 3:
             _getProductType = [NSString stringWithString:Tankmix];
             break; 
     }

    [self loadProductComponentValues];
    // Check Point
    [TestFlight passCheckpoint:@"SET_PRODUCT_TYPE"];
}

// This is Delgate Method to get selceted product
-(void) getSelectedTurftype:(NSString*) getTurftype {

    self.gotTurftype = getTurftype;
    NSLog(@"self.gotTurftype %@", self.gotTurftype);
    [self loadProductComponentValues];

    if ([_turftypePopover isPopoverVisible]) {
        [_turftypePopover dismissPopoverAnimated:YES];
    }
}

-(void) initAllTheProduct {

    _getProductType = [NSString stringWithString:AllProduct];
    self.gotTurftype = nil;

    // init the segment button value 
    [productTypeSelector setSelectedSegmentIndex:0];
    [self loadProductComponentValues];
    // Check Point
    [TestFlight passCheckpoint:@"SET_ALL_PRODUCT"];
}

- (IBAction)setAllProduct:(id)sender {

    [self initAllTheProduct];
}

// This Method use for Load Value of ProductComponent
- (NSMutableArray*) loadProductComponentValues {

    [self.resultProduct removeAllObjects]; 
    if (!_dbObject) [self loadDBAccessDatabase];

    self.resultProduct = [[NSMutableArray alloc] initWithArray:[self.dbObject getRelatedProductArray:self.gotTurftype andProductType:_getProductType]];
    [_productTableView reloadData];
    return self.resultProduct;
}

- (NSMutableArray *) loadProductComponentValuesIfEmpty {
    // NSLog(@"%s", __FUNCTION__);

    [self initAllTheProduct];
    if (!_dbObject) [self loadDBAccessDatabase];
    if (!self.resultProduct || ![self.resultProduct count]) self.resultProduct = [[NSMutableArray alloc] initWithArray:[self.dbObject getRelatedProductArray:self.gotTurftype andProductType:_getProductType]];
    // Check Point
    [TestFlight passCheckpoint:@"LOAD_DATABASE"];

    return self.resultProduct;
}

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

        NSString * _dbFileName = @"turfnutritiontool.db";
        _dbObject = [[DBAccess alloc] initWithSSDBAccessFilename:_dbFileName];
    }
    return _dbObject;
}

@end

3 个答案:

答案 0 :(得分:2)

首选使用属性访问器直接访问init...dealloc以外的方法中的实例变量。例如,您的代码目前有很多地方可以执行以下操作:

 _getProductType =  [NSString stringWithString:AllProduct];

暂且不说getProductType是一个属性的愚蠢名称(对于实例变量来说是双倍的,更不用说合成的setter方法名称将是setGetProductType),这个代码直接指定一个在不取得对象所有权的情况下反对实例变量。不要这样做。相反,请执行以下操作之一:

// First let's rename your property. In the .h file, modify the current declaration like so:
@property (nonatomic, copy) NSString *productType;

// In the .m file, change the @synthesize statement:
@synthesize productType = _productType;

// In cleaning up any compiler errors/warnings from references to the old names,
// modify code that directly assigns to the instance variable (other than in `dealloc`):

// So change this:
_getProductType =  [NSString stringWithString:AllProduct];

// to the following:
self.productType = [NSString stringWithString:AllProduct];

// ...or better yet:
self.productType = AllProduct;

// Note that the above statement is equivalent to the following:
[self setProductType:AllProduct];

修改

同样正如@samfisher正确指出的那样,在nil 发送release消息之前,请不要将ivars设置为dealloc

答案 1 :(得分:0)

使用: self._getProductType = [[NSString alloc] initWithString:AllProduct];

更改此序列:

    [_getProductType release];
    [_productTableView release];
    [_productTypeSelector release];
    [_turftypePopover release];
    [_gotTurftype release];
    [_resultProduct release];
    [_productTableCellStyle release];

   _productTableView = nil;
    _productTypeSelector = nil;
    _turftypePopover = nil;
    _gotTurftype = nil;
    _resultProduct = nil;
    _productTableCellStyle = nil;
    _getProductType = nil;

你正在将内存泄漏为设置指向nil,//内存泄漏的指针 首先你应该释放然后设置指向nil; //没有泄漏的指针

答案 2 :(得分:-2)

在此行分配 _getProductType

_getProductType = [[NSString alloc] initWithString:AllProduct];

不以任何方式保留。

只要_getProductType超出范围(在 viewDidLoad 之后),您将无法引用有效对象。

所以每当你在viewDidLoad之外引用_getProductType时,它就好像'已发布'。

你的dealloc方法正确释放它所以你所要做的就是在分配/初始化后添加'retain',因此:

_getProductType = [[[NSString alloc] initWithString:AllProduct] retain];

但是,研究属性及其工作方式可能是一个非常好的主意,如何设置它们来执行诸如保留或复制数据以及初始化时的操作。您的起点是here