// 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
这是m文件
// 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
我创建了这样的对象数组,如下所示
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];
然后我像这样保存了数组
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:theArray] forKey:@"savedArray"];
然后我像这样从磁盘加载数组。
NSData *theData = [[NSUserDefaults standardUserDefaults] objectForKey:@"savedArray"];
if (theData != nil) {
NSLog(@"found something");
theArray = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];
}
程序正常运行,直到达到此
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
detailViewController.myObject = [theArray objectAtIndex:indexPath.row];
它在最后一行崩溃了。如果我使用NSUserDefaults加载数组,它只会崩溃,但是我没有注意到那个部分我做错了。
当它崩溃时,这就是调试器所说的
*** 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'
编辑:
我能够通过替换此行来解决问题
theArray = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];
用这个liine
theArray = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];
所以我想现在的问题是为什么能解决这个问题?
答案 0 :(得分:2)
我认为您的归档/取消归档代码没有任何问题。我怀疑indexPath.row
超出了范围。
OP编辑问题后编辑:
错误消息显示:-[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x5955e50
你会注意到这意味着'theArray'实际上是指向一个NSString。在某个地方你已经为你的'theArray'变量分配了错误的东西。
在另一个OP编辑后再次编辑:
在原始代码中,您使用alloc/initWithArray:
代替arrayWithArray:
。
arrayWithArray:
用法对您不起作用,因为该方法返回一个自动释放的对象。所以当你以后使用它时,引用可能指向任何东西,因此在一种情况下它恰好指向一个字符串。