[新手学IOS]第六天:持久化应用程序(2)--属性列表序列化归档

本文介绍如何使用NSCoding协议实现对象的归档与读档功能,包括定义遵循NSCoding协议的模型类、实现归档与读档的方法以及在UIViewController中进行实际操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用到属性列表序列化,无非就是实现<NSCoding>协议.

1.首先需要建立一个coding模型:

#import <Foundation/Foundation.h>

@interface BIDForyLines : NSObject<NSCoding,NSCopying>
@property (copy,nonatomic)NSString *field1;
@property (copy,nonatomic)NSString *field2;
@property (copy,nonatomic)NSString *field3;
@property (copy,nonatomic)NSString *field4;


@end

两个重要的协议的实现如下:

#import "BIDForyLines.h"

#define kField1Key @"field1"
#define kField2Key @"field2"
#define kField3Key @"field3"
#define kField4Key @"field4"

@implementation BIDForyLines

@synthesize field1,field4,field3,field2;

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:field1 forKey:kField1Key];
    [aCoder encodeObject:field2 forKey:kField2Key];
    [aCoder encodeObject:field3 forKey:kField3Key];
    [aCoder encodeObject:field4 forKey:kField4Key];
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.field1 = [aDecoder decodeObjectForKey:kField1Key];
        self.field2 = [aDecoder decodeObjectForKey:kField2Key];
        self.field3 = [aDecoder decodeObjectForKey:kField3Key];
        self.field4 = [aDecoder decodeObjectForKey:kField4Key];
    }
    
    return self;

}

-(id)copyWithZone:(NSZone *)zone
{
    BIDForyLines *copy = [[self class]allocWithZone:zone];
    
    copy.field1 = [self.field1 copyWithZone:zone];
    copy.field2 = [self.field2 copyWithZone:zone];
    copy.field3 = [self.field3 copyWithZone:zone];
    copy.field4 = [self.field4 copyWithZone:zone];
    
    return copy;

}

然后再viewController 中进行调用和操作

#import <UIKit/UIKit.h>
#import "BIDForyLines.h"

#define kFielename @"archive"
#define kDataKey @"Data"


@interface BIDViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *field1;
@property (weak, nonatomic) IBOutlet UITextField *field2;
@property (weak, nonatomic) IBOutlet UITextField *field3;
@property (weak, nonatomic) IBOutlet UITextField *field4;

/*

 UITextFieldOutlet一定要是weak的属性(一般的Outlet都是weak),不然会出错

 [UITextInputTraits text]: unrecognized selector sent to instance 0x89950e0

 */

-(NSString *)dataFilePath; -(void)applicationWillResignActive:(NSNotification *)notification; @end


.m中的实现:

#import "BIDViewController.h"
#import "BIDForyLines.h"

//#define kFilename @"data.plist"


#define kFilename @"archive"
#define kDataKey @"Data"

@interface BIDViewController ()

@end

@implementation BIDViewController

@synthesize field1,field2,field3,field4;



-(NSString *)dataFilePath
{
    return [
            [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:kFilename
            ];
    
    
    
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.field1 = nil;
    self.field2 = nil;
    self.field3 = nil;
    self.field4 = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	[super viewDidDisappear:animated];
}


-(void)applicationWillResignActive:(NSNotification *)notification
{
    //这是对对象进行归档到硬盘
    BIDForyLines *fourLines = [[BIDForyLines alloc]init];
    fourLines.field1 = field1.text;
    fourLines.field2 = field2.text;
    fourLines.field3 = field3.text;
    fourLines.field4 = field4.text;
    
    NSMutableData *data = [[NSMutableData alloc]init];
    
    NSKeyedUnarchiver *archiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
    [archiver encodeObject:fourLines forKey:kDataKey];
    
    [archiver finishDecoding];
    [data writeToFile:[self dataFilePath] atomically:YES];
    

    
//    NSMutableArray *array = [[NSMutableArray alloc]init];
//    [array addObject:field1.text];
//    [array addObject:field2.text];
//    [array addObject:field3.text];
//    [array addObject:field4.text];
//    
//    [array writeToFile:[self dataFilePath] atomically:YES];
    
}

/*
- (void)applicationWillResignActive:(NSNotification *)notification {
    BIDForyLines *fourLines = [[BIDForyLines alloc] init];
    fourLines.field1 = field1.text;
    fourLines.field2 = field2.text;
    fourLines.field3 = field3.text;
    fourLines.field4 = field4.text;
    
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
                                 initForWritingWithMutableData:data];
    [archiver encodeObject:fourLines forKey:kDataKey];
    [archiver finishEncoding];
    [data writeToFile:[self dataFilePath] atomically:YES];
}
*/
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSString *filePath = [self dataFilePath];
    if ([[NSFileManager defaultManager]fileExistsAtPath:filePath]) {
//        NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
//        field1.text = [array objectAtIndex:0];
//        field2.text = [array objectAtIndex:1];
//        field3.text = [array objectAtIndex:2];
//        field4.text = [array objectAtIndex:3];
        
        NSData *data = [[NSMutableData alloc]initWithContentsOfFile:[self dataFilePath]];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
        BIDForyLines *fourLines = [unarchiver decodeObjectForKey:kDataKey];
        
        [unarchiver finishDecoding];
        
        field1.text = fourLines.field1;
        field2.text = fourLines.field2;
        field3.text = fourLines.field3;
        field4.text = fourLines.field4;
        
        
    }
    NSLog(@"noti");
    UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];
  
	// Do any additional setup after loading the view, typically from a nib.
}
/*
 IOS中还有一类产生事件的功能,那就是通知。通过通知,可以在一定的条件下触发响应的事件。类似于Android中的广播机制(Broadcase Receiver),接收到通知(广播)后,便可执行指定的方法。
 通过NSNotificationCenter获取通知对象,注册并使用通知。
 
 下面 以一个例子为例:
 UIApplication *application = [UIApplication sharedApplication];
 [[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(applicationWillResignActive:)name:UIApplicationWillResignActiveNotification object:application];
 
 以上代码注册了一个通知,addObserver是接收通知的对象,通常为self,selector是接收到通知后要执行的操作,可以理解为操作事件,name是通知的名称,这里使用的是UIApplicationWillResignActiveNotification,意思是应用程序将要进入后台之前,object限定只接收来自哪些对象的通知,通常设为nil
 
 -(void)applicationWillResignActive:(NSNotification *)notification
 {
 
 }
 在上面这个方法中实现响应的操作就可以了。
 
 这个过程就是当应用程序将要进入后台前(按下Home键)触发通知,然后执行applicationWillResignActive:notification方法完成一些操作。
 */

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

@end

在运行的过程中,就是因为我把textfield 属性设置成了 copy 类型的,导致最后返回到home的时候出错.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值