EXC_BAD_ACCESS 在 UIPickerView 上 - 我需要一些指导来说明为什么
EXC_BAD_ACCESS on UIPickerView - I need a bit of direction on why
我在 运行 我的项目并尝试更改选择器时收到 exc_bad_access 错误。
错误发生在
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
下面是我的代码。通过阅读其他 SO 文章,我意识到我可能没有保留我的变量。我是新手,正在学习并感谢您的帮助。
#import <UIKit/UIKit.h>
#import "RootViewController.h"
@class RootViewController;
@interface AddConditionViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UITextField *txtConditionDetail;
IBOutlet UITextField *txtConditionArea;
IBOutlet UIPickerView *conditionNamesPicker;
NSMutableArray *names;
NSMutableArray *conditionDefs;
RootViewController *rvc;
NSString *conditionName;
}
@property (retain, nonatomic) IBOutlet UIPickerView *conditionNamesPicker;
@property (nonatomic,assign) RootViewController *rvc;
@property (nonatomic, retain) NSString *conditionName;
@property (nonatomic,assign) NSMutableArray *names;
@property (nonatomic,assign) NSMutableArray *conditionDefs;
@end
#import "AddConditionViewController.h"
#import "ConditionsAppDelegate.h"
#import "Condition.h"
#import "ConditionDef.h"
#import "Formula.h"
@implementation AddConditionViewController
@synthesize rvc, conditionNamesPicker, names, conditionDefs, conditionName;
/*
// Implement loadView to create a view hierarchy programmatically.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Add Condition";
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:@selector(cancel_Clicked:)] autorelease];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self action:@selector(save_Clicked:)] autorelease];
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
conditionDefs = appDelegate.getConditionDefs;
self.names = [NSMutableArray arrayWithCapacity:[conditionDefs count]];
for (ConditionDef *def in conditionDefs) {
NSString *condition_name = def.condition_name;
if (!condition_name) {
condition_name = @"<Unknown Account>";
}
[names addObject:condition_name];
}
self.conditionNamesPicker.dataSource = self;
self.conditionNamesPicker.delegate = self;
NSLog(@"LINE 48");
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Set the textboxes to empty string.
txtConditionArea.text = @"";
txtConditionDetail.text = @"";
//Make the Category name textfield to be the first responder.
[txtConditionArea becomeFirstResponder];
NSLog(@"LINE 63");
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSLog(@" LINE 87 - COUNT OF CONDITION DEFS TO SHOW = %i", names.count);
[conditionNamesPicker setDataSource:self];
return [names count];
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
// NSLog(@"LINE 94 - here is the bug: conditionDefs[row] %@", names[row]);
return names[row];
}
// Catpure the picker view selection
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// This method is triggered whenever the user makes a change to the picker selection.
// The parameter named row and component represents what was selected.
conditionName = names[row];
}
- (void) save_Clicked:(id)sender {
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
//Create a Condition Object.
Condition *c = [[Condition alloc] init];
NSInteger newId = c.getNextConditionId;
Condition *cond = [[Condition alloc] initWithPrimaryKey:newId];
cond.condition_area = txtConditionArea.text;
cond.condition_detail = txtConditionDetail.text;
cond.condition_name = conditionName;
//Add the object
// [appDelegate addCondition:cond];
[appDelegate populateFromDatabase];
// ADD TO THE ARRAY:
// [cvc.categories addObject:cond];
// [cvc.Conditions addObject:cond];
rvc.Conditions = [appDelegate activeConditions];
// UPDATE THE TABLEVIEW
[rvc.tableView reloadData];
// release
[cond release];
[c release];
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (void) cancel_Clicked:(id)sender {
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
NSLog(@"LINE 159");
[theTextField resignFirstResponder];
return YES;
}
- (void)dealloc {
[txtConditionArea release];
[txtConditionDetail release];
[conditionNamesPicker release];
[super dealloc];
}
@end
您正在DataSource 方法之一中设置PickerView 的数据源。这是无效的。删除下面的行
[conditionNamesPicker setDataSource:self];
来自函数:
numberOfRowsInComponent:
你又在设置了。
请将名称 属性 的 属性 assign
更改为 retain
。以及其他数组或那些继承自NSObject
的对象。它是一个对象,您将其保留为分配 属性。仅对原始数据类型使用赋值。试试这个,让我知道。
我在 运行 我的项目并尝试更改选择器时收到 exc_bad_access 错误。
错误发生在
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
下面是我的代码。通过阅读其他 SO 文章,我意识到我可能没有保留我的变量。我是新手,正在学习并感谢您的帮助。
#import <UIKit/UIKit.h>
#import "RootViewController.h"
@class RootViewController;
@interface AddConditionViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UITextField *txtConditionDetail;
IBOutlet UITextField *txtConditionArea;
IBOutlet UIPickerView *conditionNamesPicker;
NSMutableArray *names;
NSMutableArray *conditionDefs;
RootViewController *rvc;
NSString *conditionName;
}
@property (retain, nonatomic) IBOutlet UIPickerView *conditionNamesPicker;
@property (nonatomic,assign) RootViewController *rvc;
@property (nonatomic, retain) NSString *conditionName;
@property (nonatomic,assign) NSMutableArray *names;
@property (nonatomic,assign) NSMutableArray *conditionDefs;
@end
#import "AddConditionViewController.h"
#import "ConditionsAppDelegate.h"
#import "Condition.h"
#import "ConditionDef.h"
#import "Formula.h"
@implementation AddConditionViewController
@synthesize rvc, conditionNamesPicker, names, conditionDefs, conditionName;
/*
// Implement loadView to create a view hierarchy programmatically.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Add Condition";
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:@selector(cancel_Clicked:)] autorelease];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self action:@selector(save_Clicked:)] autorelease];
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
conditionDefs = appDelegate.getConditionDefs;
self.names = [NSMutableArray arrayWithCapacity:[conditionDefs count]];
for (ConditionDef *def in conditionDefs) {
NSString *condition_name = def.condition_name;
if (!condition_name) {
condition_name = @"<Unknown Account>";
}
[names addObject:condition_name];
}
self.conditionNamesPicker.dataSource = self;
self.conditionNamesPicker.delegate = self;
NSLog(@"LINE 48");
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Set the textboxes to empty string.
txtConditionArea.text = @"";
txtConditionDetail.text = @"";
//Make the Category name textfield to be the first responder.
[txtConditionArea becomeFirstResponder];
NSLog(@"LINE 63");
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSLog(@" LINE 87 - COUNT OF CONDITION DEFS TO SHOW = %i", names.count);
[conditionNamesPicker setDataSource:self];
return [names count];
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
// NSLog(@"LINE 94 - here is the bug: conditionDefs[row] %@", names[row]);
return names[row];
}
// Catpure the picker view selection
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// This method is triggered whenever the user makes a change to the picker selection.
// The parameter named row and component represents what was selected.
conditionName = names[row];
}
- (void) save_Clicked:(id)sender {
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
//Create a Condition Object.
Condition *c = [[Condition alloc] init];
NSInteger newId = c.getNextConditionId;
Condition *cond = [[Condition alloc] initWithPrimaryKey:newId];
cond.condition_area = txtConditionArea.text;
cond.condition_detail = txtConditionDetail.text;
cond.condition_name = conditionName;
//Add the object
// [appDelegate addCondition:cond];
[appDelegate populateFromDatabase];
// ADD TO THE ARRAY:
// [cvc.categories addObject:cond];
// [cvc.Conditions addObject:cond];
rvc.Conditions = [appDelegate activeConditions];
// UPDATE THE TABLEVIEW
[rvc.tableView reloadData];
// release
[cond release];
[c release];
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (void) cancel_Clicked:(id)sender {
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
NSLog(@"LINE 159");
[theTextField resignFirstResponder];
return YES;
}
- (void)dealloc {
[txtConditionArea release];
[txtConditionDetail release];
[conditionNamesPicker release];
[super dealloc];
}
@end
您正在DataSource 方法之一中设置PickerView 的数据源。这是无效的。删除下面的行
[conditionNamesPicker setDataSource:self];
来自函数:
numberOfRowsInComponent:
你又在设置了。
请将名称 属性 的 属性 assign
更改为 retain
。以及其他数组或那些继承自NSObject
的对象。它是一个对象,您将其保留为分配 属性。仅对原始数据类型使用赋值。试试这个,让我知道。