当内存发布时,为什么我的加载笔尖会崩溃?

时间:2011-12-09 14:21:16

标签: iphone

如果我根据分析器运行构建和分析此加载没有错误但应用程序崩溃。如果我删除[myStates release];分析器抱怨可能的泄漏但是nib加载并运行得很好。 MyStateList是一个nib,里面有一个pickerview,如果这有帮助的话会加载一个plist。请帮忙。

主TrialViewControllerViewController实施文件

#import "TrialViewControllerViewController.h"
#import "MyStateList.h"

@implementation TrialViewControllerViewController


- (void)viewDidLoad {
[super viewDidLoad];

MyStateList *myStates = [[MyStateList alloc] initWithNibName:@"MyStateList" bundle:nil];    
[self.view addSubview:[myStates view]];  
//[myStates release];
}


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

- (void)viewDidUnload {
}


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

@end

以下是我要加载的内容

MyStateList.h

#import <UIKit/UIKit.h>

@interface MyStateList : UIViewController <UIPickerViewDelegate,  UIPickerViewDataSource> {

UIPickerView   *pickerView;
NSMutableArray *statesArray;   // Written array
NSDictionary   *stateListDictionary,*stateListDictionaries;
NSArray  *firstDisplayArray,*updateDisplayArray,*switchDisplayArray;
NSInteger  dTag;
NSString *nott,*verify,*notes;

IBOutlet UILabel *labelOne,*labelTwo,*labelThree,*labelName;
}

@property (nonatomic, retain) UIPickerView *pickerView;
@property (nonatomic, retain) NSDictionary  *stateListDictionary,*stateListDictionaries;
@property (nonatomic, retain) NSArray     *firstDisplayArray,*updateDisplayArray,*switchDisplayArray; 
@property (nonatomic, retain) IBOutlet UILabel *labelOne,*labelTwo,*labelThree,*labelName;
@property (nonatomic, retain) NSString *nott,*verify,*notes;

- (void)loadData;
- (void)placeData;
- (void)createPicker;

@end 

MyStateList.m

#import "MyStateList.h"

@implementation MyStateList
@synthesize pickerView;
@synthesize  stateListDictionary,stateListDictionaries,firstDisplayArray,updateDisplayArray,switchDisplayArray ;
@synthesize labelOne,labelTwo,labelThree,labelName;
@synthesize nott,verify,notes;

- (void)viewDidLoad 
{
[super viewDidLoad];
[self createPicker];
}

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{ 
return [statesArray count];
}


-(UIView *)pickerView:(UIPickerView *)pickerViewCust viewForRow:(NSInteger)row forComponent: (NSInteger)component reusingView:(UIView *)view
{

NSString *rowItem = [statesArray objectAtIndex: row];
UILabel *lblRow = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerViewCust bounds].size.width, 44.0f)]autorelease];
[lblRow setTextAlignment:UITextAlignmentCenter];
[lblRow setTextColor: [UIColor blueColor]];
[lblRow setText:rowItem];
[lblRow setBackgroundColor:[UIColor clearColor]];
return lblRow;
}

- (void)createPicker 
{

NSString *path = [[NSBundle mainBundle] pathForResource:
                  @"StateArray" ofType:@"plist"];

stateListDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
labelName.text     = [NSString stringWithFormat:@"Arizona"];
[self loadData];    
float screenWidth = [UIScreen mainScreen].bounds.size.width;
float pickerWidth = screenWidth * 1 / 2;
float xPoint = screenWidth / 2 - pickerWidth / 1;
pickerView = [[UIPickerView alloc] init];
[pickerView setDataSource: self];
[pickerView setDelegate: self];
[pickerView setFrame: CGRectMake(xPoint, 280.0f, pickerWidth, 180.0f)];
pickerView.showsSelectionIndicator = YES;
[pickerView selectRow:2 inComponent:0 animated:YES];
[self.view addSubview: pickerView];
}

- (void)loadData 
{

firstDisplayArray = [stateListDictionary objectForKey:@"Arizona"];
dTag = 1;
[self placeData];   
stateListDictionary = nil;  // kill the list
statesArray = [[NSMutableArray alloc] init];

[statesArray addObject:@"Alabama"];
[statesArray addObject:@"Alaska"];
[statesArray addObject:@"Arizona"];
[statesArray addObject:@"Arkansas"];
[statesArray addObject:@"California"];  
}

- (void)placeData 
{

if (dTag == 1) 
{
    switchDisplayArray = firstDisplayArray;
    dTag = 0;

} else {
    switchDisplayArray = updateDisplayArray;
}

nott     = [switchDisplayArray objectAtIndex:0];
verify   = [switchDisplayArray objectAtIndex:1];
notes    = [switchDisplayArray objectAtIndex:2];

labelOne.text      = nott;
labelTwo.text      = verify;
labelThree.text    = notes;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:    (NSInteger)component
{
NSString *path = [[NSBundle mainBundle] pathForResource:
                  @"StateArray" ofType:@"plist"];

stateListDictionaries = [NSDictionary dictionaryWithContentsOfFile:path];
labelName.text = [statesArray objectAtIndex: row];
updateDisplayArray = [stateListDictionaries objectForKey:labelName.text];
[self placeData];
}

- (void)dealloc 
{
[pickerView release];
[stateListDictionary release];
[stateListDictionaries release];
[statesArray release];
[super dealloc];


}


@end

4 个答案:

答案 0 :(得分:4)

如果我不得不猜测,MyStatesListUIViewController的子类。

如果你在块的末尾释放myStates,你基本上是从视图控制器中移除大脑,但将其身体留在那里。您需要保持控制器本身以及视图,因为视图由控制器拥有。不是相反。

视图保留视图控制器的视图,但是您杀死了视图控制器本身。更大的问题是你不能以这种方式从UIViewControllers添加视图。在iOS5上,您可以使用addChildViewController:,在此之前您可以使用其中一个提供的容器控制器。

答案 1 :(得分:1)

您确实需要发布MyStateList个对象。

以下是发生的事情:

  1. 您初始化一个新的MyStateList,其保留计数为1
  2. 您在视图中添加了一个子视图,该子视图是 MyStateList个对象,而是view对象的ivar MyStateList
  3. 当你没有释放你的myStates对象时,你确实泄漏了这个对象,因为没有任何对这个对象的引用,并且内存从未被释放。 (它的保留计数从未达到过0.)
  4. 有人说,当你的应用程序崩溃时会发生什么样的错误?我猜测MyStateListUIViewController,然后视图尝试访问/与已发布/解除分配的父级进行通信。

答案 2 :(得分:1)

-(void)dealloc;首先打电话给[super dealloc],这是错误的。使其成为方法中的最后一次调用。这应该可以解决你的崩溃问题。

- (void)dealloc 
{
// Wrong Way
[super dealloc];
[pickerView release];
[stateListDictionary release];
[stateListDictionaries release];
[statesArray release];
}

`

- (void)dealloc 
{
// Right way
[pickerView release];
[stateListDictionary release];
[stateListDictionaries release];
[statesArray release];
[super dealloc];
}

答案 3 :(得分:0)

将视图[myStates view]添加到控制器的视图中,以便控制器的视图保持视图。

然后你释放“myStates”以避免记忆泄漏,它被移除。

我想在你的视图[myStates view]中,必须有一些与对象“myState”相关的委托,但它之前被删除了。所以,应用程序崩溃。

为了避免这两个问题,内存泄漏和崩溃。我认为你应该让你的控制器将“myStates”保持为成员变量。你可以在viewUnloaded时释放“myState”。