MKPolyline -> NSKeyedArchiver -> NSData SIGABRT

В моем приложении я пытаюсь сохранить массив MKPolylines в NSUserDefaults,

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:overlays];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"theKey"];

дает:

[MKPolyline encodeWithCoder:]: unrecognized selector sent to instance 0x169c20`
Terminating app due to uncaught exception 
'NSInvalidArgumentException', reason: '-
[MKPolyline encodeWithCoder:]: unrecognized 
selector sent to instance 0x1c57e0'

Изменить: я добился определенного прогресса. MKPolylineView соответствует NSCoding протокол, поэтому я преобразовал мой массив MKPolylineс в массиве MKPolylineViews. Проблема в том, что когда я хочу добавить их обратно на карту позже, я не могу преобразовать их обратно в MKPolylines. Есть идеи, как это сделать?

Сбои в этом коде:

NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:@"theKey"];
NSArray* overlays = [NSKeyedUnarchiver unarchiveObjectWithData:data];

for(MKPolylineView* a in overlays)
    [mapView addOverlay:a.overlay];

2011-10-17 21:15:56.416 Trail Tracker[4269:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x34b2f8bf 0x36c3a1e5 0x34a8420f 0x35697595 0x6257 0x62db 0x365f77ff 0x36601d53 0x36601cc1 0x366a1339 0x366a014f 0x366fad97 0x649b 0x36671565 0x366e9ce7 0x31fcc943 0x34b03a63 0x34b036c9 0x34b0229f 0x34a854dd 0x34a853a5 0x351f9fed 0x365ec743 0x2c75 0x2c34)
terminate called throwing an exception(gdb) 

2 ответа

Решение

Я не совсем уверен в этом, но MKPolylines сделаны из массива CLLocationCoordinate2D, который содержит значение с плавающей запятой для lat и long.

Поэтому, если вы можете преобразовать этот массив CLLocationCoordinate2D в массив словаря, я думаю, что вы можете сохранить эти строки в своих пользовательских значениях по умолчанию.

Вы можете сделать что-то вроде этого

MKMapPoint *points = overlays.points;

NSMutableArray *temp = [NSMutableArray array];
for(int i = 0; i < points.length; i++)
{
    // Not sure for this part
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:points[i].x], @"x", [NSNumber numberWithFloat:points[i].y], @"y", nil];
    [temp addObject:dict];
}

Затем вы можете использовать этот массив для хранения точек наложения в nsuserdefaults, как это

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:temp];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"theKey"];

Судя по иерархии наследования NSObject -> MKShape -> MKMultiPoint -> MKPolyline, ни один из них не соответствует протоколу NSCoding. Таким образом, вы можете рассмотреть возможность наследования MKPolyline и включить протокол NSCoding и реализовать требуемый метод и использовать его.

Другие вопросы по тегам