【问题标题】:UIPickerView crashes app when scrolling past beginning or end of list滚动超过列表的开头或结尾时,UIPickerView 使应用程序崩溃
【发布时间】:2011-07-26 09:24:52
【问题描述】:

我是 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
}

【问题讨论】:

    标签: iphone view crash controller picker


    【解决方案1】:

    尝试: birdColors = [[NSArray alloc] initWithObjects:@"Blue",@"Yellow",@"Red",nil]; 而不是birdColors = [NSArray arrayWithObjects:@"Blue",@"Yellow",@"Red",nil];

    【讨论】:

    • 修复了它。你能告诉我为什么这会有所不同吗?我对内存管理有所了解,但这似乎会增加保留计数。如果我正在使用 (nonatomic,retain) 并且我在这里分配初始化,那么在 dealloc 上发布一个版本就足够了吗?感谢您的帮助。
    • 如果你这样做,@property(nonatomic, retain) 应该不是必需的,并且在你的 dealloc 中单个 [birdColors dealloc] 应该足够好。我更喜欢自己做所有的管理,而不是处理保留自动释放的对象和东西。看起来数组在自动释放池中过早释放。
    • 这是有道理的。再次感谢。
    【解决方案2】:

    像使用pickerView 一样,也使birdColors 成为一个属性(非原子,保留)。 您的数组没有被保留,因此您正在访问僵尸内存。 在可执行文件的属性/常规面板中设置 NSZombieEnabled=YES。这将准确地告诉您正在访问什么。

    【讨论】:

    • 感谢您的参与,迈克。我将数组设置为非原子并保留并像我对视图所做的那样释放它,但这并没有解决它。滚动到选择器列表的开头或结尾并释放时仍然崩溃。 (我没有看到您建议的设置 NSZombieEnabled 的位置。)
    • re:zombie - 抱歉 - 参数选项卡 - 下半部分,点击“+”,名称为 NSZombieEnabled,值为 YES,选中此框。您将看到错误地处理了哪个变量。此外,在您的 titleForRow 中:在 'return' 语句上方添加: NSLog(@" row is %d",row);
    • 好的,所以当带有选择器的视图启动时,它最初显示: 2011-03-30 14:15:44.114 BirdApp[1435:207] row is 2 2011-03-30 14:15 :44.115 BirdApp[1435:207] 行是 1 2011-03-30 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 .当我选择任何具有实际值的行时,我在输出面板中看不到任何内容。
    • 奇怪...我猜想在选择器中滚动超出列表项会导致 pickerView: titleForRow: forComponent: 再次运行,试图重新填充列表?
    • [__NSArrayI objectAtIndex:]: message sent to deallocated instance 0x603d080
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多