其实,我之前也问过同样的问题,但我还没有找到解决方法,所以我又来了。
我的情况:
我有一个UIPickerView
带有2个相关组件的,第二个或右侧组件中的行数和内容随着当前选择的第一或左侧组件中的行而变化,这是一个非常常见且有用的功能UIPickerView
。
现在,如果我使用 2 个拇指同时滚动两个组件,我的应用程序很快就会很容易崩溃,并显示以下信息:
*** Terminating app due to uncaught exception of class '_NSZombie_NSException'
libc++abi.dylib: terminate called throwing an exception
具有讽刺意味的是,我无法调试它。
实际上,如果我在方法中添加断点pickerView:didSelectRow:inComponent
,我什至不能同时快速滚动两个组件,因为每次我将手指放在屏幕上时它都会在断点处停止。
我只能猜测原因是当第一个组件被滚动时,第二个组件中的假定行数不断变化,但与此同时,它UIPickerView
正在询问第二个组件的标题和编号,然后它崩溃了。
但是我还没有找到任何可以用来判断一个组件是否被滚动的方法。所以我找不到正确的时间来拒绝pickerView
'sdelegate
和dataSource
第二个组件的请求。
有没有人遇到过类似的情况?
谢谢你的帮助!我会很感激的!
在我的代码中,这个错误是关于 的typePicker
,所以我删除了所有其他与 . 无关的代码typePicker
。
在这里,type
and是 Core Data 中的两个实体,以及一个名为reach from todetailTypes
的一对多关系。details
type
detailsTypes
例如,如果类型是“国家”,detailTypes
则将是“美国”、“法国”、“中国”等。
所以在 中typePicker
,第 1 个或左边的组件显示所有类型实体,第 2 个或右边的组件detailTypes
根据第 1 个组件中当前选择的类型显示相应的实体。
并且两个组件的第一行typePicker
总是“None”,让用户不选择特定的类型,这就是代码中有很多“+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];
}