If I run Build and Analyze this loads without errors according to the Analyzer but the app crashes. If I remove the [myStates release]; analyzer complains about possible leak but the nib loads and runs just fine. MyStateList is a nib which has a pickerview inside that loads a plist if this helps. Please help.
Main TrialViewControllerViewController Implementation File
#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
Here is what i am trying to load
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
If I had to guess,
MyStatesListis a subclass ofUIViewController.If you release
myStatesat the end of the block, you’re essentially removing the brain from your view controller, but leaving its body there. You need to keep the controller itself around as well as the view, as the view is owned by the controller. Not the other way around.The view from your view controller is retained by the view, but you killed the view controller itself. The bigger problem is you CAN’T just add views from UIViewControllers in this manner. On iOS5 you have the ability to use
addChildViewController:and prior to that you can use one of the provided container controllers.