2012-06-07 4 views
0

Я искал верхнюю и нижнюю информацию о том, как это сделать. Я приземлился на большой учебник! Поэтому я все еще новичок в этом. В основном я пытался сохранить аннотации Map View к массиву. Аннотации представляют собой отдельный класс, который в основном переопределяет/действует как MKAnnotation для аннотации булавки. Он имеет три свойства:Сохранение нескольких аннотаций карт - сбоев

  1. Аннотация
  2. Координатора
  3. Аннотация Название
  4. Аннотация Субтитры

Этот массив должен хранить в 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]; 

ответ

0

Я решил эту проблему! Я пришел к осознанию, координата двух переменных, широты и долготы - это двойники, типы данных ... НЕ объекты! Поэтому они работают и работают только ПОТОМУ ЧТО они копируются ... в отличие от объектов, которые являются ссылками. Короче говоря, мне нужно было retain. Точно так же:

 title = [[aDecoder decodeObjectForKey: @"titler"] retain]; 
     subtitle = [[aDecoder decodeObjectForKey: @"subtitler"] retain]; 
1

Я не уверен, в чем причина сбоев. Но я заметил, что некоторые ошибки в ваших закодировать методы/декодирования:

EDIT: Только если ваш супер класс соответствует NSCoding:

В encodeWithCoder вы должны по первому зову:

[super encodeWithCoder: aCoder]; 

В initWithCoder заменяющие

self = [super init]; 

по

self = [super initWithCoder:aDecoder] 

следующие возвращает неизменный объект (не NSMutableArray):

localOverlays = [NSKeyedUnarchiver unarchiveObjectWithData: data]; 

Заменить эту строку:

localOverlays = [[NSKeyedUnarchiver unarchiveObjectWithData: data] mutableCopy]; 

Я надеюсь, что помогает!

+0

Ну ... Я получаю предупреждение о том, что супер не отвечает на селектор encodeWithCoder и initWithCoder, потому что это NSObject, а не NSCoding. – MCKapur

+0

Ahhh Я вижу, что я сделал что-то не так в моем вопросе, Annotation не CONFORM для NSCoder ... – MCKapur

+0

проверить мой обновленный вопрос – MCKapur

 Смежные вопросы

  • Нет связанных вопросов^_^