请帮助我,我无法理解为什么会发生这种情况,_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
答案 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。