当用户同时旋转组件时,UIPickerView会崩溃应用程序 [英] UIPickerView crashes app when user is spinning components at the same time

查看:95
本文介绍了当用户同时旋转组件时,UIPickerView会崩溃应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UIPickerView让我遇到了无法忍受的问题。有两个组成部分:第一个是食品类别,第二个是每个类别中的食品。我有适当的食物数组,看起来像:

I've got really unbearable issue with UIPickerView. There're 2 components: first one with food categories, and second with foods inside each category. I've got proper arrays with foods, which looks like:

ViewController.h

@property (strong, nonatomic) NSArray *leftPickerDataSource;
@property (strong, nonatomic) NSArray *vegetablesDataSource;
@property (strong, nonatomic) NSArray *eggsDataSource;
@property (strong, nonatomic) NSArray *pastaDataSource;
@property (strong, nonatomic) NSArray *riceDataSource;
@property (strong, nonatomic) NSArray *meatDataSource;

ViewController.m

...
@implementation ViewController

@synthesize foodPicker;

@synthesize leftPickerDataSource;
@synthesize vegetablesDataSource;
@synthesize eggsDataSource;
@synthesize pastaDataSource;
@synthesize riceDataSource;
@synthesize meatDataSource;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.leftPickerDataSource = [NSArray arrayWithObjects: @"Vegetables", @"Eggs", @"Pasta", @"Rice", @"Meat", nil];
    self.vegetablesDataSource = [NSArray arrayWithObjects:@"Potatoes", @"Broad bean", @"Beans", @"Broccoli", @"Cabbage", @"Cauliflower", @"Corn", nil];
    self.eggsDataSource = [NSArray arrayWithObjects:@"Soft-boiled", @"Hard-boiled", nil];
    self.pastaDataSource = [NSArray arrayWithObjects:@"Pasta", @"Spaghetti", nil];
    self.riceDataSource = [NSArray arrayWithObjects:@"White", @"Brown", @"Black", @"Red", nil];
    self.meatDataSource = [NSArray arrayWithObjects:@"Sausages", @"Crabs", @"Lobsters", @"Shrimps", nil];
}

我相信数组不是问题,但当我旋转两个组件时同时选择器,应用程序通常与EXC_BAD_ACCESS崩溃(代码= 1 ...)。

I believe arrays ain't the problem, but when I spin two components of picker at the same time, the app usually crashes with EXC_BAD_ACCESS (Code=1...).

这是我的UIPickerView:

Here goes my UIPickerView:

ViewController.m

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

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource count];
        //[foodPicker selectRow:0 inComponent:1 animated:YES];
    }
    else {
        // Right picker
        NSInteger sRow = [foodPicker selectedRowInComponent:0];
        if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Eggs"])
            return [eggsDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Pasta"])
            return [pastaDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Rice"])
            return [riceDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Meat"])
            return [meatDataSource count];
    }
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource objectAtIndex:row];
    }
    else {
        // Right picker
        NSInteger sRow = [foodPicker selectedRowInComponent:0];
        if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Eggs"])
            return [eggsDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Pasta"])
            return [pastaDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Rice"])
            return [riceDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Meat"])
            return [meatDataSource objectAtIndex:row];
    }
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    if (component == 0)
        [foodPicker reloadComponent:1];
}

这里找不到任何可疑的东西。不知道为什么,但旋转车轮会使应用程序崩溃。我在SO寻找答案,但没有任何帮助:/

Can't find anything suspicious here too. Have no idea why, but spinning the wheels crashes the app. I looked for answers at SO, but nothing helps :/

你知道发生了什么事吗?

Have you any idea what's the matter?

推荐答案

实际上我的假设是错的 - 选中的行不是未定义的或是零,但是当你旋转时它会快速变化。问题是你在numberOfRowsInComponent中返回的数字取决于该方法运行时旋转拨号的位置,但是当titleForRow运行时,第一个组件位于不同的行上,并且您正在尝试访问不在存在。要修复它,你应该定义一个属性sRow,在numberOfRowsInComponent中为它赋值,然后在titleForRow中使用相同的值(不要像你现在那样重新分配),而不是获取新值。

Actually I was wrong in my supposition -- the selected row is not undefined or nil, but it's changing rapidly while you spin. The problem is that the number you return in numberOfRowsInComponent depends on where the spinning dial is when that method runs, but by the time titleForRow runs, the first component is on a different row, and you're trying to access rows that don't exist. To fix it, you should define a property sRow, assign it a value in numberOfRowsInComponent, and then use that same value (don't re-assign like you're doing now) in titleForRow, rather than getting a new value.

@property (nonatomic) NSInteger sRow;

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource count];
        //[foodPicker selectRow:0 inComponent:1 animated:YES];
    }
    else {
        // Right picker
        self.sRow = [foodPicker selectedRowInComponent:0];
        if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Eggs"])
            return [eggsDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Pasta"])
            return [pastaDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Rice"])
            return [riceDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Meat"])
            return [meatDataSource count];
    }
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource objectAtIndex:row];
    }
    else {
        // Right picker
        if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Eggs"])
            return [eggsDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Pasta"])
            return [pastaDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Rice"])
            return [riceDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Meat"])
            return [meatDataSource objectAtIndex:row];
    }
}

这篇关于当用户同时旋转组件时,UIPickerView会崩溃应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆