我有一些数据最初存储在 sqlite 中,第一次使用时会加载到 NSCache。我将数据从 NSCache 复制到 pickerview 对象并使用数据生成 pickerview(对象中的“保留”)。
但是,少数用户会因为pickerview对象中的数据不符合预期而遇到崩溃。
数据源.m:
- (NSDictionary *)getAllCurrenciesForCache {
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"CurrencyList" ofType:@"json"]];
NSDictionary *dict = [data objectFromJSONData];
return dict;
}
- (NSArray *)getCurrencyList {
NSDictionary *currencies = [cache objectForKey:@"key"];
if(!currencies){
NSDictionary *currencies = [self getAllCurrenciesForCache];
[cache setObject:currencies forKey:@"key"];
}
NSArray *keys = [currencies allKeys];
if(keys){ // do some sorting
return [keys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}
// shouldn't be here
return nil;
}
视图控制器.m:
NSArray *data = [datasource getCurrencyList];
NSMutableArray *currencies = [[NSMutableArray alloc] init];
for (NSString *abbr in data) {
[currencies addObject:[[MyClass alloc] initWithAbbr:abbr]];
}
MyPicker *picker = [[MyPicker alloc] initWithData:[NSArray arrayWithArray:currencies]];
MyPicker.h:
@property (nonatomic, retain) NSArray *currencies;
MyPicker.m:
- (id)initWithData:(NSArray *)data {
self = [super init];
if (self) {
self.currencies = data;
self.datasource = self;
self.delegate = self;
}
return self;
}
#pragma mark - UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return self.currencies.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
// sometimes crashes
MyClass *currency = self.currencies[row];
return [currency showString];
}
#pragma mark - UIPickerViewDelegate
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
[self notifySelection];
}
- (void)notifySelection {
NSInteger index = [self selectedRowInComponent:0];
// here may crash because of index out of bound
MyClass *currency = self.currencies[index];
// send the selected currency to view controller
}