NSCoding 프로토콜을 구현하는 클래스 알림이 있습니다.NSUserDefaults가 내 사용자 지정 개체를 저장하고 읽을 수 없습니다.
+ (void) initialize
{
NSUserDefaults* defaults=[NSUserDefaults standardUserDefaults];
[defaults registerDefaults: [NSDictionary dictionaryWithObject: [NSKeyedArchiver archivedDataWithRootObject: [NSArray array]] forKey: @"notificationsData"]];
}
- (id) init
{
self=[super init];
if(self)
{
NSUserDefaults* defaults=[NSUserDefaults standardUserDefaults];
NSData* notificationsData=[defaults objectForKey: @"notificationsData"];
notifications= [[NSKeyedUnarchiver unarchiveObjectWithData: notificationsData]mutableCopy];
}
return self;
}
- (void) applicationWillTerminate:(NSNotification *)notification
{
NSUserDefaults* defaults=[NSUserDefaults standardUserDefaults];
NSData* notificationsData=[NSKeyedArchiver archivedDataWithRootObject: notifications];
[defaults setObject: notificationsData forKey: @"notificationsData"];
}
알림 클래스 텍스트 :
내가 notifications.I의 배열 NSUserDefaults.In 내 응용 프로그램 위임 알림과 알림을 저장하기 위해 노력하고 있습니다 내 응용 프로그램 대리인의 objects.That 알림을 포함하는있는 NSMutableArray이다 제목 유형있는 NSString (모두 READWRITE)의, 그리고 날짜는 유형있는 NSDate (또한이 READWRITE 속성이) .This 내가 NSCoding 프로토콜을 구현하는 방법입니다 :
- (void) encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject: date forKey: @"date"];
[aCoder encodeObject: title forKey: @"title"];
[aCoder encodeObject: text forKey: @"text"];
}
- (id) initWithCoder:(NSCoder *)aDecoder
{
self=[super init];
if(self)
{
date=[aDecoder decodeObjectForKey: @"data"];
title=[aDecoder decodeObjectForKey: @"title"];
text=[aDecoder decodeObjectForKey: @"text"];
}
return self;
}
그래서 나는이 문제가를
- NSKeyedArchiver를 사용하여 텍스트를 인코딩하려고하면 응용 프로그램이 종료 될 때 알림 클래스에서 EXC_BAD_ACCESS가 발생합니다.
- 응용 프로그램이 시작될 때 알림은 저장되지 않고 배열의 길이는 항상 0입니다. 이
- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView { return [notifications count]; } - (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { // Debug id obj=[[notifications objectAtIndex: row] valueForKey: [tableColumn identifier]]; Class class=[obj class]; // What you see above is just for debug purposes return [[notifications objectAtIndex: row] valueForKey: [tableColumn identifier]]; } - (void) tableViewSelectionDidChange:(NSNotification *)notification { NSInteger row=[tableView selectedRow]; if(row >= 0 && row< [notifications count]) [removeButton setEnabled: YES]; else [removeButton setEnabled: NO]; }
라는 마지막 방법은 다음과 같습니다
업데이트 : 응용 프로그램이 crashes.There (나는 데이터를 표시하기 위해 테이블 뷰를 사용하고 있습니다) 볼 수있는 더 많은 코드가 어디에 더 디버그으로 내가 발견 이 :
- (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
아마 문제는 데이터가 어떻게 든 손상 및이 방법에 충돌하지 않는 응용 프로그램을 valid.Anyway되지 않은이 메소드에 의해 반환 된 값,하지만이 방법 후된다는 점이다.
사용자 기본값에서 두 개의 개체를로드하는 경우 충돌이 발생하기 전에 하나의 개체 만로드됩니다. 따라서 메서드가 한 번 호출됩니다.
그러나 나는 아직도 충돌의 진짜 이유를 얻을 수 없습니다.
더 코드 :
- (IBAction) addNotification :(id)sender
{
Notification* notification=[[Notification alloc]init];
[notification setDate: [datePicker dateValue]];
[notification setText: [textView string]];
[notifications addObject: notification];
[tableView reloadData];
}
- (IBAction)removeNotification:(id)sender
{
[notifications removeObjectAtIndex: [tableView selectedRow]];
[tableView reloadData];
}
에 addNotification 및 removeNotification이 두 버튼에 의해 트리거됩니다.
편집 : 내가 ARC를 사용하지 않고있는 것을 발견했지만, 앱을 켜더라도이를 해제합니다.
그래, 어쨌든 충돌이 발생해도 여전히 문제가 있습니다. –
'NSData * notificationsData = [NSKeyedArchiver archivedDataWithRootObject : notifications];를 NSData * notificationsData = [NSKeyedArchiver archivedDataWithRootObject : @ []];로 대체하면 어떻게됩니까? –
이 경우 예외가 발생하지 않고 애플리케이션이 원활하게 실행됩니다. 물론 배열이 비어 있기 때문에 이전 실행에서 알림을 복구 할 수 없습니다. 프로토콜 구현 방법에 문제가 있음을 알 수 있습니다. –