0

我有一些数据最初存储在 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
}
4

2 回答 2

1

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

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

希望有帮助。

于 2013-12-15T08:53:39.530 回答
1

我不会NSCache用于这个目的。NSCache设计用于存储内存不足时可以销毁的时间。

您将使用 NSCache 来防止应用程序访问网络或磁盘,而不是作为选择器视图或表格视图的真实来源。

从文档

NSCache 对象在以下几个方面与其他可变集合不同:

NSCache 类包含各种自动删除策略,确保它不会使用过多的系统内存。如果其他应用程序需要内存,系统会自动执行这些策略。调用时,这些策略会从缓存中删除一些项目,从而最大限度地减少其内存占用。

只需使用一个实例NSArray来支持您的选择器。

于 2013-12-15T08:56:36.783 回答