一、介绍
属性列表文件是一种XML文件,Foundation框架中的数组和字典等都可以与属性列表文件互相转换。
通过直接操作属性列表,可以实现数据持久化。
二、数组和字典读写
NSArray读写属性列表的方法:
+ (NSArray<ObjectType> *)arrayWithContentsOfFile:(NSString *)aPath
类级构造方法,用于从属性列表中读取数据,创建NSArray对象
- (NSArray<ObjectType> *)initWithContentsOfFile:(NSString *)aPath
实例构造方法,用于从属性列表中读取数据,创建NSArray对象。
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
改方法把NSArray对象写入属性列表中,他的第一个参数是文件名,第二个参数是否使用辅助文件,如果为YES先写入到一个辅助文件中,然后辅助文件再重新命名为目录文件,如果为NO,则直接写入到目标文件。
NSDictionary读写属性列表的方法与NSArray的方法基本类似,如下:
+ (NSDictionary<KeyType,ObjectType> *)dictionaryWithContentsOfFile:(NSString *)path
- (NSDictionary<KeyType,ObjectType> *)initWithContentsOfFile:(NSString *)path
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
三、例子
fileOperate.m文件操作类
1 #import "fileOperate.h" 2 3 @implementation fileOperate 4 5 //获取沙盒路径 6 - (NSString *)getDocumentPath 7 { 8 NSString * pathArr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 9 NSString * strPath = [pathArr stringByAppendingPathComponent:@"sjz.plist"]; 10 return strPath; 11 } 12 13 //将新加入的数据保存在文件中 14 - (void)addNotepad:(NSMutableDictionary *)dict 15 { 16 NSString * strPath = [self getDocumentPath]; 17 //读取文件保存在数组中 18 NSMutableArray * arr = [NSMutableArray arrayWithContentsOfFile:strPath]; 19 if(!arr){ 20 arr = [[NSMutableArray alloc] init]; 21 } 22 23 //将数据加入到数组中 24 [arr addObject:dict]; 25 //将数组写的问价中 26 [arr writeToFile:strPath atomically:YES]; 27 } 28 29 - (void)removeNotepad:(NSMutableDictionary *)dict 30 { 31 NSString * strPath = [self getDocumentPath]; 32 NSMutableArray * array = [NSMutableArray arrayWithContentsOfFile:strPath]; 33 34 for(NSMutableDictionary * dictionary in array){ 35 if([[dictionary objectForKey:@"date"] isEqualToString:[dict objectForKey:@"date"]]){ 36 //删除数据 37 [array removeObject:dict]; 38 [array writeToFile:strPath atomically:YES]; 39 break; 40 } 41 } 42 } 43 44 - (NSMutableArray *)listArr 45 { 46 NSString * strPath = [self getDocumentPath]; 47 NSMutableArray * arr = [NSMutableArray arrayWithContentsOfFile:strPath]; 48 49 return arr; 50 } 51 52 @end
JZViewController.m
1 #import "JZViewController.h" 2 #import "fileOperate.h" 3 #import "JZAddViewController.h" 4 5 @interface JZViewController ()<UITableViewDataSource, UITableViewDelegate, JZAddViewController> 6 7 @property (nonatomic, strong) UITableView * tableView; 8 @property (nonatomic, strong) fileOperate * operate; 9 @property (nonatomic, strong) NSMutableArray * listArr; 10 11 @end 12 13 @implementation JZViewController 14 15 - (void)viewDidLoad { 16 [super viewDidLoad]; 17 self.title = @"记事本"; 18 19 self.operate = [[fileOperate alloc] init]; 20 self.listArr = [self.operate listArr]; 21 22 [self initTableView]; 23 [self createNavButton]; 24 } 25 26 - (void)createNavButton 27 { 28 // self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Edit" style:UIBarButtonItemStyleDone target:self action:@selector(editNotepad)]; 29 /** 30 *将左键设置成编辑按钮,这个是视图控制器已经存在的,它可以获取编辑按钮的对象指针 31 *编辑按钮的样式可以咋Edit和Done之间转换,如果切换取决于当前的视图是否处于编辑状态。 32 *点击时,会调用会调用setEditing:animated:方法 33 */ 34 self.navigationItem.leftBarButtonItem = self.editButtonItem; 35 if(self.listArr.count <= 0){ 36 self.editButtonItem.enabled = NO; 37 } 38 39 self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Add" style:UIBarButtonItemStyleDone target:self action:@selector(addNotepad)]; 40 } 41 42 - (void)initTableView 43 { 44 UITableView * tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; 45 tableView.backgroundColor = [UIColor whiteColor]; 46 tableView.delegate = self; 47 tableView.dataSource = self; 48 tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 49 [self.view addSubview:tableView]; 50 51 self.tableView = tableView; 52 } 53 54 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 55 { 56 return 1; 57 } 58 59 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 60 { 61 return self.listArr.count; 62 } 63 64 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 65 { 66 static NSString * strID = @"JZViewController"; 67 UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:strID]; 68 if(!cell){ 69 cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strID]; 70 }else{ 71 for(UIView * view in [cell.contentView subviews]){ 72 [view removeFromSuperview]; 73 } 74 } 75 76 NSMutableDictionary * dict = [self.listArr objectAtIndex:indexPath.row]; 77 78 UILabel * label1 = [[UILabel alloc] initWithFrame:CGRectMake(15, 5, [UIScreen mainScreen].bounds.size.width - 30, 40)]; 79 label1.text = [dict objectForKey:@"text"]; 80 label1.font = [UIFont systemFontOfSize:17]; 81 label1.textAlignment = NSTextAlignmentLeft; 82 label1.textColor = [UIColor blackColor]; 83 [cell.contentView addSubview:label1]; 84 85 UILabel * label2 = [[UILabel alloc] initWithFrame:CGRectMake(15, 45, [UIScreen mainScreen].bounds.size.width - 30, 20)]; 86 label2.text = [dict objectForKey:@"date"]; 87 label2.font = [UIFont systemFontOfSize:15]; 88 label2.textAlignment = NSTextAlignmentLeft; 89 label2.textColor = [UIColor blackColor]; 90 [cell.contentView addSubview:label2]; 91 92 UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 79.5, [UIScreen mainScreen].bounds.size.width, 0.5)]; 93 view.backgroundColor = [UIColor grayColor]; 94 [cell.contentView addSubview:view]; 95 return cell; 96 } 97 98 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 99 { 100 return 80; 101 } 102 103 //在编辑状态下,设置单元格是增加还是删除 104 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 105 { 106 return UITableViewCellEditingStyleDelete; 107 } 108 109 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 110 { 111 //删除完毕后,将左边按钮,设置为Edit 112 [self setEditing:NO]; 113 114 NSMutableDictionary * dict = [self.listArr objectAtIndex:indexPath.row]; 115 [self.operate removeNotepad:dict]; 116 //删除数据,数据来源于哪里,就删除哪里的数据 117 [self.listArr removeObjectAtIndex:indexPath.row]; 118 //删除cell的方法 119 [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 120 [self.tableView reloadData]; 121 122 if(self.listArr.count <= 0){ 123 self.editButtonItem.enabled = NO; 124 } 125 } 126 127 //是否显示高亮状态 128 - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath 129 { 130 return NO; 131 } 132 133 //跳转到JZAddViewController 134 - (void)addNotepad 135 { 136 JZAddViewController * add = [[JZAddViewController alloc] init]; 137 add.delegate = self; 138 [self.navigationController pushViewController:add animated:YES]; 139 } 140 141 //JZAddViewController代理方法,增加数据后,刷新列表 142 - (void)loadViewData 143 { 144 self.listArr = [self.operate listArr]; 145 [self.tableView reloadData]; 146 if(self.listArr.count > 0){ 147 self.editButtonItem.enabled = YES; 148 } 149 } 150 151 //该方法是UIViewController的生命周期方法,用于响应视图编辑状态的变化,也就是editing参数 152 - (void)setEditing:(BOOL)editing animated:(BOOL)animated 153 { 154 [super setEditing:editing animated:animated]; 155 156 [self.tableView setEditing:editing animated:animated]; 157 } 158 159 @end
JZAddViewController是增加数据类
1 #import <UIKit/UIKit.h> 2 3 @protocol JZAddViewController <NSObject> 4 5 - (void)loadViewData; 6 7 @end 8 9 @interface JZAddViewController : UIViewController 10 11 @property (nonatomic, strong) id<JZAddViewController> delegate; 12 13 @end
1 #import "JZAddViewController.h" 2 #import "fileOperate.h" 3 4 @interface JZAddViewController () <UITextViewDelegate> 5 6 @property (nonatomic, strong) UITextView * textView; 7 @property (nonatomic, strong) UIButton * button; 8 9 @end 10 11 @implementation JZAddViewController 12 13 - (void)viewDidLoad { 14 [super viewDidLoad]; 15 self.view.backgroundColor = [UIColor whiteColor]; 16 self.title = @"添加"; 17 self.automaticallyAdjustsScrollViewInsets = NO; 18 19 //添加手势,让textView放弃第一响应者 20 UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture)]; 21 [self.view addGestureRecognizer:tap]; 22 23 [self initTextView]; 24 [self initButton]; 25 } 26 27 - (void)initTextView 28 { 29 UITextView * textView = [[UITextView alloc] initWithFrame:CGRectMake(15, 74, [UIScreen mainScreen].bounds.size.width - 30, 150)]; 30 //画边框,圆角 31 textView.layer.borderColor = [UIColor grayColor].CGColor; 32 textView.layer.borderWidth = 0.5; 33 textView.layer.cornerRadius = 5.0; 34 35 textView.font = [UIFont systemFontOfSize:14]; 36 textView.textColor = [UIColor grayColor]; 37 38 [self.view addSubview:textView]; 39 40 self.textView = textView; 41 } 42 43 - (void)initButton 44 { 45 UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(20, 150 + 74 + 10, [UIScreen mainScreen].bounds.size.width - 40, 40)]; 46 button.layer.borderColor = [UIColor grayColor].CGColor; 47 button.layer.borderWidth = 0.5; 48 button.layer.cornerRadius = 5.0; 49 50 [button setTitle:@"确定" forState:UIControlStateNormal]; 51 [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; 52 [button addTarget:self action:@selector(addNotes) forControlEvents:UIControlEventTouchUpInside]; 53 54 [self.view addSubview:button]; 55 56 self.button = button; 57 } 58 59 //添加nodes 60 - (void)addNotes 61 { 62 NSMutableDictionary * dict = [[NSMutableDictionary alloc] init]; 63 [dict setObject:self.textView.text forKey:@"text"]; 64 65 NSDate * date = [NSDate date]; 66 NSDateFormatter * formatter = [[NSDateFormatter alloc] init]; 67 [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 68 NSString * str = [formatter stringFromDate:date]; 69 [dict setObject:str forKey:@"date"]; 70 71 fileOperate * operater = [[fileOperate alloc] init]; 72 [operater addNotepad:dict]; 73 74 [self.navigationController popViewControllerAnimated:YES]; 75 76 if([self.delegate performSelector:@selector(loadViewData)]){ 77 [self.delegate loadViewData]; 78 } 79 } 80 81 //手势响应函数 82 - (void)tapGesture 83 { 84 [self.textView resignFirstResponder]; 85 } 86 87 @end