2012-04-24 1 views
0

Я работаю над созданием приложения, которое использует сам созданный мной класс, Запись, для хранения определенных данных в массиве. Тем не менее, я продолжаю сталкиваться с этой ошибкой, когда пытаюсь получить доступ к одному из значений, хранящихся в объекте Entry. Каждый раз, когда я предлагаю пользователю создать один из этих объектов, он добавляется в «rawArray», который, в свою очередь, хранится в [NSUserDefaults standardUserDefaults]. В этих строках кода, программа падает:Не знаю, как обращаться с «Завершающим приложением из-за неперехваченного исключения» NSInvalidArgumentException »

Entry *currEntry = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"rawArray"] objectAtIndex:section]; 
NSLog(@"date: %@", [currEntry getDate]); 

Я только пытаюсь вытащить элемент массива, соответствующий текущему разделу UITableView, а затем NSLog «датой» переменная хранится в нем. Вот метод GetDate из класса Входа:

-(NSString *)getDate{ 
    return date; 
} 

Дата сам объект является еще одним NSString в классе входа, который устанавливается в инициализации класса. Если кто-то может помочь мне разобраться в этой проблеме, я был бы невероятно благодарен.

Вот полный журнал аварии:

2012-04-24 16:31:32.545 Know[7278:f803] -[__NSCFString getDate]: unrecognized selector sent to instance 0x68598f0 
2012-04-24 16:31:32.546 Know[7278:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString getDate]: unrecognized selector sent to instance 0x68598f0' 
*** First throw call stack: 
(0x13cb052 0x155cd0a 0x13ccced 0x1331f00 0x1331ce2 0xa930 0xb85c9 0xb8480 0x1fc849 0x1ff722 0xaf7c7 0xaf2c1 0xb228c 0xb6783 0x61301 0x13cce72 0x1d7592d 0x1d7f827 0x1d05fa7 0x1d07ea6 0x1d9330c 0x33530 0x139f9ce 0x1336670 0x13024f6 0x1301db4 0x1301ccb 0x12b4879 0x12b493e 0x22a9b 0x1d98 0x1cf5) 
terminate called throwing an exception 

После того как я перешел к использованию NSKeyedArchiver/распаковщик, я все еще столкнулся с той же проблемой. Вот мои новые извлечь и сохранить методы:

-(void)saveToUserDefaults:(NSMutableArray *)array{ 
    NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:array]; 
    [[NSUserDefaults standardUserDefaults] setObject:myEncodedObject forKey:@"rawArray"]; 
} 

-(NSMutableArray *)loadFromUserDefaults{ 
    NSData *myDecodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"rawArray"]; 
    NSMutableArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: myDecodedObject]; 
    return decodedArray; 
} 

Вот новые строки кода, сбою программы:

Entry *currEntry = [[self loadFromUserDefaults] objectAtIndex:section]; 
NSLog(@"date: %@", [currEntry getDate]); 

А вот обновленный журнал аварии:

2012-04-24 17:43:36.853 Know[10314:f803] -[__NSCFString getDate]: unrecognized selector sent to instance 0x6acc260 
2012-04-24 17:43:36.904 Know[10314:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString getDate]: unrecognized selector sent to instance 0x6acc260' 
*** First throw call stack: 
(0x13ce052 0x155fd0a 0x13cfced 0x1334f00 0x1334ce2 0xb710 0xbb5c9 0xbb480 0x1ff849 0x202722 0xb27c7 0xb22c1 0xb528c 0xb9783 0x64301 0x13cfe72 0x1d7892d 0x1d82827 0x1d08fa7 0x1d0aea6 0x1d9630c 0x36530 0x13a29ce 0x1339670 0x13054f6 0x1304db4 0x1304ccb 0x12b7879 0x12b793e 0x25a9b 0x2a18 0x2975) 
terminate called throwing an exception 

ответ

2

Я думаю, что это связано с тем, что вы храните массив настраиваемых объектов через NSUserDefaults. Возможно, вы должны проверить эту статью об этом: How to Save array of custom class in NSUserDefaults или это question.

EDIT


Вы добавили методы encodeWithCoder и initWithCoder. Возможно, проблема заключается в ее реализации.

+0

Я переключил свою программу на использование NSKeyedArchiver/Unarchiver, но все равно имею ту же проблему. См. Обновленное сообщение для всего, что вам может понадобиться. – insanj

1

Что именно то, что заставляет ваше приложение вылетать из этих строк? Существует 3 возможных случая:

  1. Доступ к элементам, индексированным @ "rawArray" из стандартногоUserDefaults.
  2. Доступ к индексу раздела из этого массива.
  3. Доступ к дате ввода.

Я бы поспорил, что проблема связана с вашим классом Entry и NSUserDefaults. Чтобы сохранить объект в userDefaults, он должен соответствовать протоколу NSCoding (уже существуют NSArray и NSDictionary, а базовые типы также могут использоваться с их соответствующими методами).

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

Просто постарайся быть немного понятнее, какой метод приведет к сбою вашего приложения. Удачи!

+0

Я только что переключился на использование NSKeyedArchiver/Unarchiver, чтобы узнать, была ли проблема с чтением массива из standardUserDefaults. К сожалению, проблема еще не решена. Вы можете увидеть все обновления в главном сообщении выше. :/ – insanj

+0

Хорошо. Я не знаю, что происходит. Посмотрим, сможет ли кто-нибудь помочь тебе. И будьте осторожны с извлечением из пользовательских значений по умолчанию для изменяемого массива: изменяемые массивы хранятся как не изменяемые массивы, поэтому после его принятия вы должны вызвать [NSMutableArray arrayWithArray: arrayFromUserDefaults]. –

1

Использование NSKeyedArchiver первым (перед сохранением их в NSUserDefaults)

так:

сохранить:

NSData *dataForNSUserDefaults = [NSKeyedArchiver archivedDataWithRootObject:yourEntry]; 
[[NSUserDefaults standardUserDefaults] setObject:dataForNSUserDefaults forKey:@"yourKey"]; 

нагрузка:

NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"yourKey"]; 
Entry *yourEntry = [NSKeyedUnarchiver unarchiveObjectWithData:arrayAsData]; 
+0

Спасибо! Но после этого моя проблема все еще сохраняется.См. Обновленную основную запись для новой информации. :/ – insanj

1

Сообщение об ошибке говорит о том, что вещь, которую вы считаете записью, на самом деле является строкой. Сначала я предполагаю, что вы пытаетесь сохранить пользовательский тип объекта, который преобразуется в строковое описание типа. Попробуйте войти объект, чтобы увидеть точно:

NSLog(@"Entry: %@", currEntry); 

Посмотрите документацию NSUserDefaults о типах данных, чтобы увидеть, что он поддерживает.

+0

Хм, я думаю, вы что-то наделали. Когда я NSLog'd currEntry, я получил: 'currEntry: sdfAWV a17: 49: 28' (это правильный текст и дата!). Тем не менее, я думал, что уже переопределил метод описания в своем описании Entry class- '- (NSString *) { NSLog (@" Entry: text =% @ date =% @ ", text, date); return [NSString stringWithFormat: @ "Entry: text =% @ date =% @", text, date]; } ', поэтому я не уверен, что происходит. Какие-либо предложения? :/ – insanj

1

NSUserDefaults не может хранить экземпляры пользовательских классов. Он может хранить только простые вещи, такие как строки, булевы и словари.

Именно поэтому вы получаете [__NSCFString getDate]: unrecognized selector sent to instance. __NSCFString является одним из частных классов Apple для NSString. В основном это говорит о том, что ваш звонок NSUserDefaults вернул NSString, а NSString не имеет метода, называемого getDate.

Вам необходимо сериализовать и десериализовать свои данные, поэтому для хранения ваших объектов в NSUserDefaults вам необходимо сначала преобразовать ваш объект в словарное представление всех значений. Затем, когда вы хотите преобразовать свои данные обратно в объект, вы делаете обратное. Ключевое значение кодирования обычно полезно.

Кстати, getDate не совместим с классом Objective-C. Если у вас есть синтезированное свойство в классе с именем date, вы должны иметь имя свойства date, а затем синтезировать его с помощью @synthesize date = _date;. @synthesize будет писать ваши методы getter и setter (accessor and mutator) для вас, поэтому вы можете просто позвонить setData: или data, и он выяснит, что делать. Если вы используете ARC или кодирование с ключом, это особенно важно, потому что в некоторых случаях среда выполнения предполагает, что вы следите за их рекомендациями.

И, наконец, очень полезно использовать NSUserDefaults для того, для чего он предназначен - значения по умолчанию. Это будет включать настройки и другую неконфиденциальную информацию. Производительность не велика, если вы начнете делать много изменений и запросов. Используйте plist, который вы сохраняете, в каталог Documents, SQLite или Core Data.

+0

О, ничего себе, я понятия не имел о многом. Большое спасибо за то, что сообщили мне обо всем этом. Хотя я все еще недооцениваю проблему (теперь я использую NSKeyArchiver, и это не решило проблему), я буду прыгать прямо на борт, чтобы исправить все остальные. Филлип Миллс также сообщил мне о возможной проблеме NSString - см. Комментарий, который я оставил на своем посту для получения результатов. – insanj

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

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