I made a class. This is the h file.
// MyClass.h
#import <Foundation/Foundation.h>
@interface MyClass : NSObject <NSCoding> {
NSString *string1;
NSString *string2;
}
@property (nonatomic, retain) NSString *string1;
@property (nonatomic, retain) NSString *string2;
@end
This is the m file
// MyClass.m
#import "MyClass.h"
@implementation MyClass
@synthesize string1, string2;
- (void)encodeWithCoder:(NSCoder *)coder;
{
NSLog(@"encodeWithCoder");
[coder encodeObject:string1 forKey:@"string1"];
[coder encodeObject:string2 forKey:@"string2"];
}
- (id)initWithCoder:(NSCoder *)coder;
{
NSLog(@"initWithCoder");
self = [super init];
self.string1 = [coder decodeObjectForKey:@"string1"];
self.string2 = [coder decodeObjectForKey:@"string2"];
return self;
}
- (void)dealloc {
[string1 release];
[string2 release];
[super dealloc];
}
@end
I created an array of these objects like this
MyClass *object1 = [[MyClass alloc] init];
object1.string1 = @"object1 string1";
object1.string2 = @"string1 string2";
MyClass *object2 = [[MyClass alloc] init];
object2.string1 = @"object2 string1";
object2.string2 = @"object2 string2";
theArray = [[NSMutableArray alloc] initWithObjects:object1, object2, nil];
Then I saved the array like this
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:theArray] forKey:@"savedArray"];
Then I loaded the array from disk like this.
NSData *theData = [[NSUserDefaults standardUserDefaults] objectForKey:@"savedArray"];
if (theData != nil) {
NSLog(@"found something");
theArray = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];
}
The program runs normally without error until it gets to this
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
detailViewController.myObject = [theArray objectAtIndex:indexPath.row];
It crashes on that last line. It only crashes if I load the array using NSUserDefaults, however I don't notice anything I did wrong with that part.
When it crashes this is what the debugger says
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x5955e50'
*** Call stack at first throw:
(
0 CoreFoundation 0x02395919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x024e35de objc_exception_throw + 47
2 CoreFoundation 0x0239742b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x02307116 ___forwarding___ + 966
4 CoreFoundation 0x02306cd2 _CF_forwarding_prep_0 + 50
5 custom object array save test 0x00002872 -[RootViewController tableView:didSelectRowAtIndexPath:] + 156
6 UIKit 0x0032b718 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
7 UIKit 0x00321ffe -[UITableView _userSelectRowAtIndexPath:] + 219
8 Foundation 0x00038cea __NSFireDelayedPerform + 441
9 CoreFoundation 0x02376d43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
10 CoreFoundation 0x02378384 __CFRunLoopDoTimer + 1364
11 CoreFoundation 0x022d4d09 __CFRunLoopRun + 1817
12 CoreFoundation 0x022d4280 CFRunLoopRunSpecific + 208
13 CoreFoundation 0x022d41a1 CFRunLoopRunInMode + 97
14 GraphicsServices 0x02bfa2c8 GSEventRunModal + 217
15 GraphicsServices 0x02bfa38d GSEventRun + 115
16 UIKit 0x002c7b58 UIApplicationMain + 1160
17 custom object array save test 0x00002160 main + 102
18 custom object array save test 0x000020f1 start + 53
19 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Edit:
I was able to fix the problem by replacing this line
theArray = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];
with this liine
theArray = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];
so I guess the question now is why did that solve the problem?