为什么我的应用程序崩溃

时间:2010-09-20 00:15:55

标签: objective-c cocoa-touch class nsmutablearray nsuserdefaults

我上了课。这是h文件。

//  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]];

所以我想现在的问题是为什么能解决这个问题?

1 个答案:

答案 0 :(得分:2)

我认为您的归档/取消归档代码没有任何问题。我怀疑indexPath.row超出了范围。

OP编辑问题后编辑:

错误消息显示:-[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x5955e50

你会注意到这意味着'theArray'实际上是指向一个NSString。在某个地方你已经为你的'theArray'变量分配了错误的东西。

在另一个OP编辑后再次编辑:

在原始代码中,您使用alloc/initWithArray:代替arrayWithArray:

arrayWithArray:用法对您不起作用,因为该方法返回一个自动释放的对象。所以当你以后使用它时,引用可能指向任何东西,因此在一种情况下它恰好指向一个字符串。