UIPickerView аварийно завершает работу приложения при прокрутке за начало или конец списка

Я новичок в разработке iOS, поэтому, вероятно, это легко исправить. У меня есть настраиваемый контроллер представления, в котором я использую протоколы для управления UIPickerView в пике. Все работает нормально, если в симуляторе iPad я не прокручиваю средство выбора за первым элементом в списке или последним элементом в списке и не отпускаю. Это вызывает следующую ошибку:

Поток 1: Программа получила сигнал: «EXC_BAD_ACCESS»

в этой строке моего класса main.m:

int retVal = UIApplicationMain (argc, argv, nil, nil);

Соответствующий код:

ViewController.h

@interface BirdColorViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> {
IBOutlet UIPickerView *birdColorPicker;
NSArray *birdColors;
}

@property (nonatomic,retain) IBOutlet UIPickerView *birdColorPicker;

Viewcontroller.m

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

...

- (void)viewDidLoad
{
    [super viewDidLoad];
    birdColors = [NSArray arrayWithObjects:@"Blue",@"Yellow",@"Red",nil];

    birdColorPicker.delegate = self;
    birdColorPicker.dataSource = self;
}

...

#pragma mark - UIPickerViewDataSource methods

//(UIPickerView *)thePickerView

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

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

 #pragma mark - UIPickerViewDelegate methods

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 
{
    return [birdColors objectAtIndex:row];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
{
    // Set value in prefs/model
}

person Gregir    schedule 30.03.2011    source источник


Ответы (2)


Попробуйте: birdColors = [[NSArray alloc] initWithObjects:@"Blue",@"Yellow",@"Red",nil]; вместо birdColors = [NSArray arrayWithObjects:@"Blue",@"Yellow",@"Red",nil];

person Dmacpro    schedule 30.03.2011
comment
Это исправило это. Можете ли вы объяснить мне, почему это имело значение? Я немного знаю об управлении памятью, но похоже, что это увеличит счетчик удержания. Если я использую (неатомный, сохраняющий), и я использую здесь alloc-init, достаточно ли одной версии на dealloc? Спасибо за вашу помощь. - person Gregir; 31.03.2011
comment
@Property (неатомный, сохранить) не должен быть необходим, если вы делаете это таким образом, и в вашем dealloc достаточно одного [birdColors dealloc]. Я предпочитаю выполнять все управление самостоятельно, а не заниматься сохранением автоматически выпущенных объектов и прочего. Похоже, что массив был преждевременно выпущен в пул автозапуска. - person Dmacpro; 31.03.2011
comment
В этом есть смысл. Еще раз спасибо. - person Gregir; 31.03.2011

Сделайте birdColors также свойством (неатомарным, сохраните), как вы это делаете с pickerView. Ваш массив не сохраняется, поэтому вы обращаетесь к зомби-памяти. Установите NSZombieEnabled = YES на панели свойств / Общие вашего исполняемого файла. Это точно скажет вам, к чему осуществляется доступ.

person Rayfleck    schedule 30.03.2011
comment
Спасибо за участие, Майк. Я установил для массива неатомный режим, сохранил и отпустил его, как и в случае с представлением, но это не помогло. По-прежнему вылетает при прокрутке за пределы начала или конца списка выбора и отпускании. (Я не видел, где установить NSZombieEnabled, как вы посоветовали.) - person Gregir; 31.03.2011
comment
re: zombie - извините - вкладка «Аргументы» - нижняя половина, нажмите +, имя - NSZombieEnabled, значение - ДА, установите флажок. Вы увидите, к какой переменной обращаются неправильно. Кроме того, в вашем titleForRow: добавьте это над оператором return: NSLog (@ row is% d, row); - person Rayfleck; 31.03.2011
comment
Хорошо, поэтому, когда запускается представление с средством выбора, оно изначально говорит: 2011-03-30 14: 15: 44.114 BirdApp [1435: 207], строка 2 2011-03-30 14: 15: 44.115 BirdApp [1435: 207] строка 1 30 марта 2011 г. 14: 15: 44.116 BirdApp [1435: 207] строка 0code, но когда я прокручиваю начало и отпускаю, например, я получаю 2011-03-30 14: 16: 01.399 BirdApp [ 1435: 207] строка 2 2011-03-30 14: 16: 01.400 BirdApp [1435: 207] *** - [__ NSArrayI objectAtIndex:]: сообщение, отправленное освобожденному экземпляру 0x603d080. Когда я выбираю любую из строк с фактическим значением, я ничего не вижу на панели вывода. - person Gregir; 31.03.2011
comment
Странно ... Я предполагаю, что что-то в прокрутке за пределами элементов списка в средстве выбора заставляет pickerView: titleForRow: forComponent: снова запускаться, пытаясь повторно заполнить список? - person Gregir; 31.03.2011
comment
[__NSArrayI objectAtIndex:]: сообщение, отправленное в освобожденный экземпляр 0x603d080 ‹***************************************************************** Можете ли вы опубликовать код, в котором вы определяете свою собственность и вашу сделку? - person Rayfleck; 31.03.2011
comment
ViewController.h @interface BirdColorViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> { IBOutlet UIPickerView *birdColorPicker; NSArray *birdColors; } @property (nonatomic,retain) IBOutlet UIPickerView *birdColorPicker; @property (nonatomic,retain) NSArray *birdColors; @end - person Gregir; 31.03.2011
comment
Из ViewController.m @synthesize birdColorPicker; @synthesize birdColors; - (void)dealloc { [birdColorPicker release]; [birdColors release]; [super dealloc]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. birdColors = [NSArray arrayWithObjects:@"Blue",@"Yellow",@"Red",nil]; birdColorPicker.delegate = self; birdColorPicker.dataSource = self; } - person Gregir; 31.03.2011
comment
Спасибо, что остался со мной, Майк. Теперь я знаю немного больше о том, как отлаживать. - person Gregir; 31.03.2011
comment
Попробуйте self.birdColors = [NSArray arrayWithObjects ... - person Rayfleck; 31.03.2011