Я искал верхнюю и нижнюю информацию о том, как это сделать. Я приземлился на большой учебник! Поэтому я все еще новичок в этом. В основном я пытался сохранить аннотации Map View к массиву. Аннотации представляют собой отдельный класс, который в основном переопределяет/действует как MKAnnotation
для аннотации булавки. Он имеет три свойства:Сохранение нескольких аннотаций карт - сбоев
- Аннотация
Координатора- Аннотация Название
- Аннотация Субтитры
Этот массив должен хранить в NSUserDefaults
. Я столкнулся с проблемой, вот лог:
[UIMutableIndexPath SetObject: forKey]: непризнанные селектор направлен например 0x1187b0
Мои объекты класса аннотаций, хранящихся в массиве не могут быть сохранены в пользователь по умолчанию. Поэтому мне пришлось превратить этот массив в NSData
, а затем сохранить его, не так ли?
У меня есть много настроек кода, просто не работает. Вот как я пытаюсь все это:
View Controller Class.m:
- (void)syncMap { // this method is called in viewWillDissapear (for running tests) and applicationDidEnterBackground in App Delegate
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: localOverlays]; // this is the array I was talking about
[defaults setObject:data forKey:@"overlays"];
[defaults synchronize];
}
- (void)initCircles { // called in AppDelegate UIApplicationDelegate method: applicationDidFinishLaunchingWithOptions
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey: @"overlays"];
localOverlays = [NSKeyedUnarchiver unarchiveObjectWithData: data];
if (!localOverlays) {
// Either there is a problem or it is the first time opening the app
localOverlays = [[NSMutableArray alloc] init];
}
}
ПРИМЕЧАНИЕ: Я проверяю С ДВУМЯ АННОТАЦИИ В ARRAY (localOverlays
)
Итак, мой localOverlays
может быть закодированный/архивированный (с использованием NSCoder
), так как это NSArray
. Однако мне пришлось добавить некоторые дополнительные настройки в мой класс Annotation. В его .h он использует NSCoding
и MKAnnotation
: как показано ниже: < NSCoding, MKAnnotation>
. Извините, если я не использую правильный термин. Вот мой .m:
- (void)encodeWithCoder:(NSCoder *)aCoder { // should only be called when app enters background state, but since that cannot log in the console, like before I set it up so it should also be called in viewWillDissapear
NSLog(@"encodeCoder called in Annotation"); // gets called twice when the view will disappear... GOOD!
[aCoder encodeObject: title forKey: @"title"];
[aCoder encodeObject: subtitle forKey: @"subtitle"];
[aCoder encodeDouble: coordinate.latitude forKey: @"latitude"];
[aCoder encodeDouble: coordinate.longitude forKey: @"longitude"];
}
- (id)initWithCoder:(NSCoder *)aDecoder { // Should be called only at startup of app (not the first time you startup the app though... because data will be NULL)
NSLog(@"In the Annotation class, initWithCoder is called"); // Does get called at appropriate times twice... NICE!
self = [super init];
if (self) {
title = [aDecoder decodeObjectForKey: @"title"];
subtitle = [aDecoder decodeObjectForKey: @"subtitle"];
double lat = [aDecoder decodeDoubleForKey: @"latitude"];
double lon = [aDecoder decodeDoubleForKey: @"longitude"];
coordinate = CLLocationCoordinate2DMake(lat, lon);
}
return self;
}
Итак, как вы можете видеть, у меня есть все, что нужно для архивирования, не так ли? Ну, кажется, нет ... потому что теперь в ом в ViewController, у меня есть этот код в viewDidLoad:
for (Annotation *pin in localOverlays) {
if (pin) {
NSLog(@"valid pin: _CMD updateCircles");
[mapView addAnnotation: pin];
}
}
Этот код работает красиво и точно в первый раз, когда я открываю мое приложение и добавить контакты. Итак, теперь я вышел из представления и вышел из приложения и удалился из панели многозадачности. Когда я открываю его обратно вверх, я получаю сбой при быстрой нумерации строки:
-[NSURL countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0xcd31140
Таким образом, есть что-то не так со всем моим архивирования и настройки кодирования. Что здесь не так ... Я знаю, что это был длинный вопрос, но я попытался его правильно структурировать. Я устанавливаю свой код полностью неправильно, есть ли опечатка/ошибка в моем коде. Спасибо всем!
UPDATE:
Я получил переменную координату закодированный, поэтому, когда я запуск приложения после штифта появится справа координата, но когда я пытаюсь нажать на нее, чтобы увидеть заголовок и подзаголовок, я получаю после аварии:
objc_msgSend
Так что что-то выпущено прямо ... просто догадка ... плохое управление памятью? Что может вызвать этот крах в моем коде?
UPDATE:
Я смотрел глубже и дальше в мой код и изменил несколько release
заявления вокруг, только улучшил мое управление памятью и сделал немного оптимизации. Теперь я получаю более конкретный крах:
*** -[CFString length]: message sent to deallocated instance 0x147490
Так что мой заголовок или подзаголовок освобожден ... почему? Я проверил мой код он должен быть абсолютно нормально, тем более, что координаты прекрасны ...
UPDATE:
Я решил эту проблему! Я пришел к осознанию, координата двух переменных, широты и долготы - это двойники, типы данных ... НЕ объекты! Поэтому они работают и работают только ПОТОМУ ЧТО они копируются ... в отличие от объектов, которые являются ссылками. Короче говоря, мне нужно было retain
. Точно так же:
title = [[aDecoder decodeObjectForKey: @"titler"] retain];
subtitle = [[aDecoder decodeObjectForKey: @"subtitler"] retain];
Ну ... Я получаю предупреждение о том, что супер не отвечает на селектор encodeWithCoder и initWithCoder, потому что это NSObject, а не NSCoding. – MCKapur
Ahhh Я вижу, что я сделал что-то не так в моем вопросе, Annotation не CONFORM для NSCoder ... – MCKapur
проверить мой обновленный вопрос – MCKapur