ios - 使用 NSCache 作为 pickerview 的数据源可能会崩溃

标签 ios objective-c crash uipickerview nscache

我有一些数据本来是存放在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;
}

ViewController.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
}

最佳答案

NSCache 中的数据不稳定,而且非常不一致。我相信如果您将应用程序置于后台然后重新打开它,您可能会崩溃,这将删除 NSCache

在这种情况下你不应该使用它,我相信,我会建议使用 NSArray,如果数据不是那么大,或者使用 CoreData 如果它们

希望对您有所帮助。

关于ios - 使用 NSCache 作为 pickerview 的数据源可能会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20592222/

相关文章:

ios - 在 ios 的 tableview 中的选定单元格上设置 imageview 的问题

ios - 如何在不同的 UICollectionView 单元格中显示不同的视频?

objective-c - CGEventTapCreate 在 macOS Mojave 中返回 null

iPhone 在导航 Controller 动画期间崩溃,我有什么选择?

javascript - UWP javascript 崩溃

ios - 如何在不使应用程序崩溃的情况下将 TextField.text 转换为 int?在 Swift2 中

ios - 如何在 danielgindi iOS 图表中创建多个 y 轴折线图?

ios - 我们可以使用 Twilio iOS SDK 进行 VOIP 推送通知吗?

ios - 使用对象属性从 NSArray 中过滤重复项

objective-c - 如果我们设置 header "Content-Length",NSHTTPURLResponse 的 initWithURL 方法会崩溃