为什么会崩溃?

nod*_*nja 0 crash cocoa-touch objective-c nsuserdefaults nsmutablearray

我上了课.这是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
Run Code Online (Sandbox Code Playgroud)

这是m文件.

//  MyClass.m
#import "MyClass.h"


@implementation MyClass
@synthesize string1, string2;

- (void)encodeWithCoder:(NSCoder *)coder;
{
    if (self = [super init]){
        [coder encodeObject:string1 forKey:@"string1"];
        [coder encodeObject:string2 forKey:@"string2"]; 
    }

}

- (id)initWithCoder:(NSCoder *)coder;
{
    self = [[MyClass alloc] init];
    if (self != nil)
    {
        string1 = [coder decodeObjectForKey:@"string1"];
        string2 = [coder decodeObjectForKey:@"string2"];

    }   
    return self;
}

- (void)viewDidUnload {
    self.string1 = nil;
    self.string2 = nil;
}


- (void)dealloc {
    [super dealloc];
    [string1 release];
    [string2 release];
}


@end
Run Code Online (Sandbox Code Playgroud)

我创建了这样的对象数组,如下所示:

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];
Run Code Online (Sandbox Code Playgroud)

然后我像这样保存了数组:

  [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:theArray] forKey:@"savedArray"];
Run Code Online (Sandbox Code Playgroud)

然后我像这样从磁盘加载数组.

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
    NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];
    if (dataRepresentingSavedArray != nil)
    {
        NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
        if (oldSavedArray != nil)
        {
            theArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
        }
        else {

            theArray = [[NSMutableArray alloc] init];
        }


    }
Run Code Online (Sandbox Code Playgroud)

当程序到达此行时程序崩溃 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

cell.textLabel.text = [[theArray objectAtIndex:indexPath.row] string1];
Run Code Online (Sandbox Code Playgroud)

为什么会在那里崩溃?如果我不从NSUserDefaults加载数组,它不会崩溃.但是,我没有看到任何我在保存或加载数组时遇到的错误.

编辑:我也可以用这行代码使其崩溃:

NSLog(@"%@", [[theArray objectAtIndex:0] string1]) ;
Run Code Online (Sandbox Code Playgroud)

Jam*_*ton 6

除了cobbal的优点之外,你的initWithCoder:方法不使用setter,因此不保留字符串.当您尝试string1在崩溃线上访问时,该字符串可能已经被释放.在这样做initWithCoder:,而不是:

self.string1 = [coder decodeObjectForKey:@"string1"];
self.string2 = [coder decodeObjectForKey:@"string2"];
Run Code Online (Sandbox Code Playgroud)

为了解决cobbal的第一点,不要做任何初始化encodeWithCoder:.只需编码您的对象.有关编码和解码对象的更多详细信息,请查看Apple的Cocoa Archives and Serializations编程指南.

  • @synthesize语句有效地为您编写setter和getter方法; 你仍然可以打电话给他们.正如ustun指出的那样,self.string1 = @"z"被[self setString1:@"z"]取代,而string1 = @"z"只是设置string1而不调用setter. (2认同)