2014-03-01 33 views
1

我试图将位置数组保存到NSUserDefaults。首先,我将CLLocationCoordinates转换为一个NSValues数组,并使用NSUserDefaults进行保存。 这是到目前为止我的代码:将NSMutable阵列保存到NSUserDefaults时出错

_locationsArray = [[NSMutableArray alloc] init]; 
NSUInteger count = [self.locations count]; 
CLLocationCoordinate2D coordinates[count]; 
for (NSInteger i = 0; i < count; i++) { 
    coordinates[i] = [(CLLocation *)self.locations[i] coordinate]; 
    NSValue *locationValue = [NSValue valueWithMKCoordinate:coordinates[i]]; 
    [_locationsArray addObject:locationValue]; 
} 
NSLog(@"location = %@", _locationsArray); 
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

[defaults setObject:totalDistance forKey:@"totalDistance"]; 
[defaults setObject:_locationsArray forKey:@"mapOverlay"]; 
// [defaults setDouble:_totalTime forKey:@"totalTime"]; 
[defaults setObject:avgSpeedToBeSaved forKey:@"averageSpeed"]; 
[defaults setObject:totalCalories forKey:@"totalCalories"]; 
[defaults synchronize]; 

不过,我得到以下错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSUserDefaults setObject:forKey:]: attempt to insert non-property list object (
    "<8b4df1d9 36ab4240 d5059bbe 47825ec0>", 
    "<f6dd639f 36ab4240 a2a7b7f5 49825ec0>", 
    "<f6dd639f 36ab4240 a2a7b7f5 49825ec0>", 
    "<20c46379 36ab4240 5ff02732 4c825ec0>", 
    "<20c46379 36ab4240 5ff02732 4c825ec0>", 
    "<d24c9c81 36ab4240 2bd75f9f 4e825ec0>", 
    "<d24c9c81 36ab4240 2bd75f9f 4e825ec0>", 
    "<d810b96c 36ab4240 f4d96401 51825ec0>", 
    "<d810b96c 36ab4240 f4d96401 51825ec0>" 
) for key mapOverlay' 

我想,如果我转换的坐标NSValues会被罚款保存到NSUserDefaults的 - 是那不是这种情况?我应该怎么做呢?

+4

阅读'NSUserDefaults'的文档。 'NSValue'不是支持的数据类型之一。 – rmaddy

+0

相关:[为什么NSUserDefaults无法在iPhone SDK中保存NSMutableDictionary?](http://stackoverflow.com/questions/471830/why-nsuserdefaults-failed-to-save-nsmutabledictionary-in-iphone-sdk/471920#471920) –

+0

只是想提一个可能更简单的替代方法:而不是NSValues,尝试定义一个自定义类X,该类将坐标保存为NSNumber属性。然后将X的实例添加到数组中。另一种选择是包含坐标为NSNumbers的字典数组。 – Anna

回答

0

你为什么要保存NSMutableArrayNSUserDefaults。这不是保存数据的正确方法。

您应该将您的数据保存在plist文件中。

[_locationsArray writeToFile:path atomically:YES]; 

plist文件

_locationsArray=[NSMutableArray arrayWithContentsOfFile:path]; 

您还可以使用数据库中获取的所有位置。

+0

我认为这可能是我的选择,但当我尝试从plist文件中检索数据时,我的位置数组为空,这里是我正在使用的代码:'NSString * path = [NSTemporaryDirectory()stringByAppendingPathComponent:@“ActivityCompleted。的plist“]; _locationsArray = [NSMutableArray arrayWithContentsOfFile:path];''和'NSString * path = [NSTemporaryDirectory()stringByAppendingPathComponent:@“ActivityCompleted.plist”]; _locationsArray = [NSMutableArray arrayWithContentsOfFile:path];'检索 – Khledon

0

那么你可以使用NSKeyedArchiever来实现你的数组,并将其设置为userdefaults。而当你想读取相同的unarchieve使用NSKeyedUnarchiever你的数组。

0

尝试保存值而不是对象。

[defaults setValue:(id) forKey:(NSString *)]; 

它的工作,因为(id)基本上可以是“任何东西”,它不会崩溃。 :)

+0

不,我仍然得到相同的错误,即使我保存为一个值 – Khledon

0

以及它要求一个“属性列表对象”这是NSDictionary/XML/Plist。尝试将其保存到字典?

for (NSInteger i = 0; i < count; i++) { 
    coordinates[i] = [(CLLocation *)self.locations[i] coordinate]; 
    NSValue *locationValue = [NSValue valueWithMKCoordinate:coordinates[i]]; 
    [_locationsArray addObject:locationValue]; 
} 
NSMutableDictionary *locationsDict = @{@"locationsArray": _locationsArray}; 

[defaults setObject:locationsDict forKey:@"mapOverlay"]; 
[defaults synchronize]; 

让我们知道这是否正常工作:)

+0

感谢您的建议。只是一个简单的问题:我想保存位置数组的原因是我可以用它在下一个视图中构建MKPolyline,我将如何从NSDictionary重建数组? – Khledon

+0

NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; NSMutableArray * mapOverlay = [[defaults objectForKey:@“mapOverlay”] valueForKey:@“locationsArray”]; – emotality