Wan*_*ang 3 crash objective-c uipickerview ios nszombies
实际上,之前我问了同样的问题,但我还没有办法解决它,所以我又来了.
我的情况:
我有一个UIPickerView带有2个相关组件,第二个或右侧组件中行的数量和内容随第一个或左侧组件中当前选定的行而变化,这是一个非常常见且有用的函数UIPickerView.
现在,如果我使用2个拇指将两个组件一起滚动,我的应用程序很容易崩溃,很快就会有以下信息:
*** Terminating app due to uncaught exception of class '_NSZombie_NSException'
libc++abi.dylib: terminate called throwing an exception
Run Code Online (Sandbox Code Playgroud)
具有讽刺意味的是,我无法调试它.
实际上,如果我在pickerView:didSelectRow:inComponent方法中添加一个断点,我甚至不能快速地将两个组件一起滚动,因为每次我只是将手指放在屏幕上它就会在断点处停止.
我只能猜测原因是当滚动第一个组件时,第二个组件中假定的行数不断变化,但同时,UIPickerView它要求第二个组件的标题和编号,然后崩溃.
但我还没有找到任何可用于判断组件是否正在滚动的方法.所以我找不到正确的时间来拒绝pickerView's delegate和dataSource第二个组件的请求.
有没有人遇到类似的情况?
谢谢你的帮助!我很感激!
在我的代码中,错误是关于typePicker,所以我删除了所有其他与之无关的代码typePicker.
这里,type它detailTypes是Core Data中的两个实体,并且称为detailsfrom type到to的多对多关系detailsTypes.
例如,如果类型是"国家",那么detailTypes它将是"美国","法国","中国"等.
因此typePicker,在第一个或第二个组件显示所有类型实体,第二个或右侧组件detailTypes根据第一个组件中当前选择的类型显示相应的实体.
并且两个组件的第一行typePicker始终为"无",以允许用户不选择特定类型,这就是代码中有许多"+1"的原因.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
if (pickerView == self.typePicker)
return 2;
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
NSUInteger majorTypeRow = [self.typePicker selectedRowInComponent:0] - 1;
if (pickerView == self.typePicker) {
if (component == 0)
return [self.types count] + 1;
else {
if (majorTypeRow == -1) // no major type entities
return 1;
NSString *majorTypeName = [[self.types objectAtIndex:majorTypeRow] name];
NSArray *detailType = [self.detailTypes objectForKey:majorTypeName];
if (detailType)
return [detailType count] + 1;
else {
NSManagedObject *majorType = [self.types objectAtIndex:majorTypeRow];
NSSet *minorTypes = [majorType valueForKey:@"details"];
NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:@"order" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sd, nil];
NSArray *array = [minorTypes sortedArrayUsingDescriptors:sortDescriptors];
[self.detailTypes setObject:array forKey:majorTypeName];
[sd release];
return [array count] + 1;
}
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSUInteger majorTypeRow = [self.typePicker selectedRowInComponent:0] - 1;
row--;
if (pickerView == self.typePicker) {
if (component == 0)
[pickerView reloadComponent:1]; // I believe this is where the bug starts, but I can't find the exact line of code that causes the crash
else {
if (row == -1)
self._detailType = nil;
else {
NSString *majorTypeName = [[self.types objectAtIndex:majorTypeRow] name];
NSArray *dt = [self.detailTypes objectForKey:majorTypeName];
if (dt)
self._detailType = [dt objectAtIndex:row];
}
}
}
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
[self.tableView reloadData];
[self.tableView selectRowAtIndexPath:path animated:YES scrollPosition:UITableViewScrollPositionNone];
}
Run Code Online (Sandbox Code Playgroud)
崩溃是由于您的代表中的这一行
NSUInteger majorTypeRow = [self.typePicker selectedRowInComponent:0] - 1;
Run Code Online (Sandbox Code Playgroud)
正如其他人指出的那样,您需要保留两个单独的数组或对象,这些数组或对象可以为各个组件提供dataSource.
你有一个majorType和detailType.你可以有一个majorTypes和一个数组selectedMajorType.保留额外的selectedMajorType消除了使用selectedRowInComponent:该应用程序的需要,并且不再使应用程序崩溃.
#pragma mark - UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSInteger rows = 0;
if (component) {
rows = [self.selectedMajorType.minorTypes count];
}else{
rows = [self.majorTypes count];
}
return rows+1;
}
Run Code Online (Sandbox Code Playgroud)
UIPickerViewDelegate实现
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
row--;
NSString *title = @"None";
if (component) {
NSArray *minorTypes = [self.selectedMajorType.minorTypes allObjects];
if (row >= 0 && row < [minorTypes count]) {
MinorType *minorType = minorTypes[row];
title = minorType.name;
}
}else{
if(row>=0 && row < [self.majorTypes count]){
MajorType *majorType = self.majorTypes[row];
title = majorType.name;
}
}
return title;
}
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
row--;
if (component==0) {
if (row >= 0 && row < [self.majorTypes count]) {
self.selectedMajorType = self.majorTypes[row];
}else {
self.selectedMajorType = nil;
}
[pickerView reloadComponent:1];
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2384 次 |
| 最近记录: |