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

これがview 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;
 }

次に、クラスのオーバーライドdescriptionまたはdebugDescriptionメソッドを実行して、そのクラスに関するカスタム情報を返すことができます。

于 2013-03-09T02:54:09.203 に答える