0

嗨,我正在尝试借助保存到磁盘的类将数据保存在文件中。它正在保存数据但不检索正确的数据。请帮帮我

这是我的 ViewController.h

@interface MIGViewController : UIViewController
- (IBAction)hideKeyboard:(id)sender;
@property (strong, nonatomic) NSMutableArray * myArray;
@property (strong, nonatomic) NSString * pathToFile;
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *idField;
@property (weak, nonatomic) IBOutlet UITextField *addressField;
@property (weak, nonatomic) IBOutlet UITextField *phoneField;
- (IBAction)addButtonTapped:(id)sender;
- (IBAction)saveButtonTapped:(id)sender;

@end

这是视图 Controller.m

#import "MIGViewController.h"
#import "MIGStudent.h"

@interface MIGViewController ()

@end

@implementation MIGViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentsPath = [paths objectAtIndex:0];
    self.pathToFile = [documentsPath stringByAppendingPathComponent:@"students.sukh"];

    NSFileManager * manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:self.pathToFile])
    {
        //File exists
        self.myArray = [NSKeyedUnarchiver unarchiveObjectWithFile:self.pathToFile];

        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"Students array" message:[self.myArray description]delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil];
        [alert show];
    }
    else
    {
        //File doesn't exist
        self.myArray = [NSMutableArray array];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)addButtonTapped:(id)sender {
    NSString * name =self.nameField.text;
    NSString * address = self.addressField.text;
    int studentID = [self.idField.text intValue];
    int phoneNumber = [self.phoneField.text intValue];
    MIGStudent * student = [[MIGStudent alloc] initWithName:name address:address studentID:studentID phoneNumber:phoneNumber];
    [self.myArray addObject:student];
    self.nameField.text = @"";
    self.addressField.text = @"";
    self.idField.text = @"";
    self.phoneField.text = @"";
}

- (IBAction)saveButtonTapped:(id)sender {
    [NSKeyedArchiver archiveRootObject:self.myArray toFile:self.pathToFile];
}
- (IBAction)hideKeyboard:(id)sender {
    [self resignFirstResponder];
}
@end

这是我的班级 Student.h

@interface MIGStudent : NSObject <NSCoding>

@property (strong, nonatomic) NSString * name;
@property (strong, nonatomic) NSString * address;
@property (nonatomic) int studentID;
@property (nonatomic) int phoneNumber;

-(id)initWithName:(NSString *) name address:(NSString *)address studentID: (int)studentID phoneNumber:(int) phoneNumber;

@end

这是Student.m

#import "MIGStudent.h"

@implementation MIGStudent

-(id) initWithName:(NSString *)name address:(NSString *)address studentID:(int)studentID phoneNumber:(int)phoneNumber
{
    if (self=[super init])
    {
        self.name = name;
        self.address = address;
        self.phoneNumber = phoneNumber;
        self.studentID = studentID;
    }
    return self;
}

-(void) encodeWithCoder:(NSCoder *)aCoder
{
   //Used when saving to disk
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.address forKey:@"address"];
    [aCoder encodeInt:self.phoneNumber forKey:@"phoneNumber"];
    [aCoder encodeInt:self.studentID forKey:@"studentID"];
}

-(id) initWithCoder:(NSCoder *)aDecoder
{
    //Used when reading from disk
    self.name = [aDecoder decodeObjectForKey:@"name"];
    self.address = [aDecoder decodeObjectForKey:@"address"];
    self.phoneNumber = [aDecoder decodeIntForKey:@"phoneNumber"];
    self.studentID = [aDecoder decodeIntForKey:@"studentID"];

    return self;
}
@end

这是我每次认为一切正常但在检索数据时出现问题时得到的输出

在此处输入图像描述

提前致谢

4

2 回答 2

1

这对您的 NSCoding 实现来说不是问题,实际上这根本不是问题!这就是 NSArray 从字面上打印自己的方式(该-description方法的结果)。它这样做的事实表明归档/取消归档过程进展顺利。数组是括号 () 的集合,其中的对象格式为<Class : memory address>. 如果您有一个无效对象数组,那么您的数组很可能会拒绝打印,或者在将学生对象添加到其中时崩溃。

您可以在课堂上利用这一点MIGStudent并覆盖-description以打印更友好的格式。例如:

-(NSString*)description {
    return [NSString stringWithFormat:@"<%@ : %p Student named: %@ - who lives at: %@ With the ID number: %d and the phone number: %d>", NSStringFromClass(self.class), self, self.name, self.address, self.studentID, self.phoneNumber];
}

作为旁注,初始化程序总是调用 super。您的initWithCoder:方法将始终返回 nil。

于 2013-03-09T02:36:30.547 回答
0

您的initWithCoder:方法不正确,它将失败,因为当前它将返回 nil 或一些垃圾值,它应该是:

-(id) initWithCoder:(NSCoder *)aDecoder
{
     self = [super init];
     if (self)
     {
         //Used when reading from disk
         self.name = [aDecoder decodeObjectForKey:@"name"];
         self.address = [aDecoder decodeObjectForKey:@"address"];
         self.phoneNumber = [aDecoder decodeIntForKey:@"phoneNumber"];
         self.studentID = [aDecoder decodeIntForKey:@"studentID"];
     }

     return self;
 }

其次,您可以覆盖您的类的方法descriptiondebugDescription方法以返回有关该类的自定义信息。

于 2013-03-09T02:54:09.203 回答