我努力将多个位置保存到plist文件中供以后使用, 经过一段谷歌搜索后,我发现一个CLLocation本身的数组无法保存, 所以我想知道如何做到这一点。
我正在考虑几个课程,以及#34;序列化" /" deserilize"将单个CLLocation对象放入NSDictionary,然后将这些NSDictionaries的数组存储到plist文件中,但我想知道是否有更好/更智能/可靠的方法来实现它。
提前感谢。
编辑:
这是我用来保存plist中的数据的函数(c_propertyName从答案中获取代码)
- (void) addLocation {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"/Locations.plist"];
NSArray *keys = [curLocation c_propertyNames];
NSDictionary *dict = [curLocation dictionaryWithValuesForKeys:keys];
[dict writeToFile: path atomically:YES];
}
编辑2 - 解决方案:
好的,我已经全力以赴了。在下面,我已经发布了一个针对我自己的问题的两个选项解决方案。
答案 0 :(得分:3)
KVC很容易。
这是获取属性名称的NSObject类别的方法(需要<objc/runtime.h>
)
- (NSArray *)c_propertyNames {
Class class = [self class];
u_int count = 0;
objc_property_t *properties = class_copyPropertyList(class, &count);
if (count <= 0) {
return nil;
}
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, count)];
NSMutableSet *retVal = [NSMutableSet setWithCapacity:count];
[set enumerateIndexesWithOptions:NSEnumerationConcurrent
usingBlock:^(NSUInteger idx, BOOL *stop) {
const char *propName = property_getName(properties[idx]);
NSString *name = [NSString stringWithUTF8String:propName];
[retVal addObject:name];
}];
return [retVal allObjects];
}
然后像这样使用它:
NSArray *keys = [yourLocation c_propertyNames];
NSDictionary *dict = [yourLocation dictionaryWithValuesForKeys:keys];
然后保存该字典。
答案 1 :(得分:3)
我喜欢solution 2,但是如果所有人都想直接写入文件,那么序列化会更简单。
[NSKeyedArchiver archiveRootObject:arrayOfLocations toFile:path];
答案 2 :(得分:0)
S O L U T I O N - 1
感谢mit3z的帮助,我可以把各个部分组合起来找出解决方案。
正如他指出的那样,你可以将这个方法实现到NSObject的一个类别中:
- (NSArray *)c_propertyNames;
(看看他对这部分代码的回应以及有关它的更多细节)
这让我有自由做这件事:
- (void) addLocation {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"/Locations.plist"];
NSArray *keys = [curLocation c_propertyNames]; // retrieve all the keys for this obj
NSDictionary *values = [self.curLocation dictionaryWithValuesForKeys:keys];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for(NSString *key in keys) {
NSString *aaa = [NSString stringWithFormat:@"%@", (NSString *)[values valueForKey:key]];
[dict setValue:aaa forKey:key];
}
[dict writeToFile:path atomically:YES];
}
需要使用superdumb for循环将NSDictionary中的所有数据转换为NSStrings,以便它们可以毫无困难地写入plist文件,如果你只是制作字典然后你试图立即保存它,你想要没成功。
通过这种方式,我可以将所有CLLocation obj“序列化”到一个字典中,然后写入一个plist文件。
S O L U T I O N - 2
我提出了一种非常简单(也更优雅)的方法:使用 NSCoding 。 由于(我意识到) CLLocation 数据类型符合 NSCoding 的事实,您可以通过 NSKeyedArchiver 调用数据存档器以获取blob描述你的数组,然后将它存储到plist,就像那样:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"/Locations.plist"];
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
[data setValue:[NSKeyedArchiver archivedDataWithRootObject:arrayOfLocations] forKey:@"LocationList"];
[data writeToFile:path atomically:YES];
[data release];
并且瞧'就那么简单! :)
基于相同的原则,您可以通过 NSKeyUnarchiver 轻松获取数据:
self.arrayOfLocations = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData: (NSData *)[dict objectForKey:@"LocationList"]]];