大綱
一、文件管理器
項目:FileManager0412
NSFileManager:文件管理器(單例類)
作用:管理文件/文件夾
(一)獲取路徑
1.獲取home文件夾
2.獲取Documents文件夾(拼接字符串)
3.獲取指定文件路徑(拼接字符串)
(二)文件文件夾的 創(chuàng)建/拷貝/移動/刪除/屬性
1.獲取文件管理器
2.處理路徑
3.管理器調(diào)用方法(創(chuàng)建/拷貝/移動/刪除/屬性)
二、多行選擇
項目:SelectMutableLine0412
程序再次運(yùn)行時讀取數(shù)據(jù):
1.創(chuàng)建基本表
2.處理單元格的 選中/取消選中
2.1 判斷點擊的Cell索引是否在_selectedRowArr中:
①在,取消選中
換圖片 取消選中
移除 索引
②不在,選中
換圖片 選中
添加 索引
3.數(shù)據(jù)存儲(通知)
程序?qū)⒁K止運(yùn)行時,發(fā)出通知,存儲數(shù)據(jù)
4.數(shù)據(jù)讀取
程序再次運(yùn)行時,從沙盒中取出數(shù)據(jù)
三、對象序列化
項目:ObjectSerialization0412
NSUserDefaults/writeToFile不能直接存儲自定義類
結(jié)論:
數(shù)組/字典/字符串/NSData可以直接使用NSUserDefaults/writeToFile的方式將數(shù)據(jù)寫入沙盒,因為這些類都實現(xiàn)了NSCoding協(xié)議
將自定義類對象寫入沙盒的條件:
1.實現(xiàn)NSCoding協(xié)議
2.對象序列化
(一)序列化 方法1
序列化:
NSKeyedArchiver:編碼器
作用:將一個實現(xiàn)NSCoding協(xié)議的對象轉(zhuǎn)換為二進(jìn)制數(shù)據(jù)(NSData)
1.編碼
2.寫入沙盒
反序列化:
NSKeyedUnarchiver:解碼器
1.讀取數(shù)據(jù)
2.解碼
(二)方法2
序列化:
1.創(chuàng)建容器NSMutableData,保存要編碼的對象
2.創(chuàng)建序列化器,指定要編碼的對象容器
3.編碼
4.結(jié)束編碼
5.寫入文件
反序列化:
1.讀取數(shù)據(jù)
2.創(chuàng)建編碼器
3.解碼
4.結(jié)束解碼
四、對容器類的拷貝
項目:FullyCopy0412
完全拷貝
方法1:
initWithArray:copyItems:對數(shù)組中的每一個元素調(diào)用 copy方法
條件:
1.元素實現(xiàn) NSCoping 協(xié)議
2.元素是可變對象
方法2:序列化
條件:數(shù)組/元素 必須實現(xiàn) NSCoding 協(xié)議
正文
一、文件管理器
項目:FileManager0412
NSFileManager:文件管理器(單例類)
作用:管理文件/文件夾
(一)獲取路徑
1.獲取home文件夾
NSString *homeDirectoryPath = NSHomeDirectory();
2.獲取Documents文件夾(拼接字符串)
NSString *docPath = [homeDirectoryPath stringByAppendingPathComponent:@"Documents"];
3.獲取指定文件路徑(拼接字符串)
NSString *filePath = [docPath stringByAppendingPathComponent:fileName];
(二)文件文件夾的 創(chuàng)建/拷貝/移動/刪除/屬性
1.獲取文件管理器
2.處理路徑
3.管理器調(diào)用方法(創(chuàng)建/拷貝/移動/刪除/屬性)
創(chuàng)建
[fileManager createFileAtPath:path contents:[@"123" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
[fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
拷貝/移動
[fileManager copyItemAtPath:path1 toPath:path2 error:&error];
[fileManager moveItemAtPath:path1 toPath:path2 error:&error];
刪除
[fileManager removeItemAtPath:path error:&error];
屬性
NSDictionary *dic = [fileManager attributesOfItemAtPath:path error:&error];
源碼:
@implementation ViewController
#pragma mark - **************** 獲取文件路徑
- (NSString *)getFilePath:(NSString *)fileName
{
NSString *homeDirectoryPath = NSHomeDirectory();
NSLog(@"%@",homeDirectoryPath);
NSString *docPath = [homeDirectoryPath stringByAppendingPathComponent:@"Documents"];
NSString *filePath = [docPath stringByAppendingPathComponent:fileName];
return filePath;
}
#pragma mark - **************** 創(chuàng)建文件
- (IBAction)createFile:(UIButton *)sender
{
//NSFileManager:文件管理器(單例類)
//用于管理文件/文件夾
//1.獲取文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//2.獲取路徑
NSString *filePath = [self getFilePath:@"a.plist"];
BOOL isExists = [fileManager fileExistsAtPath:filePath];
if (isExists)
{
NSLog(@"該路徑下存在該文件。");
}
else
{
NSLog(@"不存在,創(chuàng)建");
//3.創(chuàng)建文件
//AtPath:在哪個路徑下創(chuàng)建
//contents:添加文件內(nèi)容
//attributes:文件屬性,nil表示默認(rèn)屬性
[fileManager createFileAtPath:filePath contents:[@"123" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
}
}
#pragma mark - **************** 創(chuàng)建文件夾
- (IBAction)createDirectory:(UIButton *)sender
{
//1.獲取文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//2.獲取路徑
NSString *directoryPath = [self getFilePath:@"class/student"];
BOOL isExists = [fileManager fileExistsAtPath:directoryPath];
if (isExists)
{
NSLog(@"該路徑下存在該文件。");
}
else
{
NSLog(@"不存在,創(chuàng)建");
//1.AtPath:在哪個路徑下創(chuàng)建文件夾
//2.withIntermediateDirectories:是否創(chuàng)建中間級文件夾
//3.attributes:文件夾屬性
//4.error:若創(chuàng)建失敗,返回錯誤原因
NSError *error = nil;
BOOL isSuccess = [fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:&error];
//判斷文件夾是否創(chuàng)建成功
if (isSuccess == NO)
{
NSLog(@"創(chuàng)建失敗,原因:%@",error);
}
}
}
#pragma mark - **************** 拷貝
- (IBAction)copyClick:(UIButton *)sender
{
NSFileManager *fileManager = [NSFileManager defaultManager];
//1.源路徑
NSString *filePath = [self getFilePath:@"a.plist"];
//2.目標(biāo)路徑
NSString *tmpPath = NSTemporaryDirectory();
NSString *filePath2 = [tmpPath stringByAppendingPathComponent:@"b.plist"];
//3.拷貝
NSError *error = nil;
[fileManager copyItemAtPath:filePath toPath:filePath2 error:&error];
}
#pragma mark - **************** 移動
- (IBAction)moveClick:(UIButton *)sender
{
NSFileManager *manager = [NSFileManager defaultManager];
//1.源路徑
NSString *path1 = [self getFilePath:@"class"];
//2.目標(biāo)路徑
NSString *path2 = [NSTemporaryDirectory() stringByAppendingPathComponent:@"class2"];
//3.移動
NSError *error = nil;
[manager moveItemAtPath:path1 toPath:path2 error:&error];
}
#pragma mark - **************** 刪除
- (IBAction)deleteClick:(UIButton *)sender
{
NSFileManager *manager = [NSFileManager defaultManager];
//1.路徑
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"class2/student"];
//2.刪除
NSError *error = nil;
[manager removeItemAtPath:path error:&error];
}
#pragma mark - **************** 獲取文件屬性
- (IBAction)attributeClick:(UIButton *)sender
{
NSFileManager *manager = [NSFileManager defaultManager];
//1.路徑
NSString *path = [self getFilePath:@"a.plist"];
NSError *error = nil;
NSDictionary *dic = [manager attributesOfItemAtPath:path error:&error];
NSDate *date = [dic fileCreationDate];
NSLog(@"date = %@",date);
}
@end
二、多行選擇
項目:SelectMutableLine0412
程序再次運(yùn)行時讀取數(shù)據(jù):
1.創(chuàng)建基本表
2.處理單元格的 選中/取消選中
2.1 判斷點擊的Cell索引是否在_selectedRowArr中:
①在,取消選中
換圖片 取消選中
移除 索引
②不在,選中
換圖片 選中
添加 索引
3.數(shù)據(jù)存儲(通知)
程序?qū)⒁K止運(yùn)行時,發(fā)出通知,存儲數(shù)據(jù)
①獲取filePath②writeToFile。
4.數(shù)據(jù)讀取
程序再次運(yùn)行時,從沙盒中取出數(shù)據(jù)
①獲取fileManager②獲取filePath③讀取
源碼:
static NSString *cellId = @"cell";
@implementation ViewController
/**
1.創(chuàng)建基本表
2.處理單元格的選中
3.處理取消單元格選中
4.數(shù)據(jù)存儲(通知)
5.數(shù)據(jù)讀取
*/
- (void)viewDidLoad
{
[super viewDidLoad];
//當(dāng)程序退出時,系統(tǒng)會發(fā)出通知
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(saveData) name:UIApplicationWillTerminateNotification object:nil];
//1.數(shù)據(jù)源
_movieArr = [[NSMutableArray alloc]initWithObjects:@"火鍋英雄",@"奇幻森林",@"X特遣隊",@"尋龍訣",@"瘋狂動物城",@"倫敦陷落",@"蜘蛛俠",@"1",@"落",@"俠", nil];
//每次啟動程序,先從沙盒中讀取數(shù)據(jù)_selectedRowArr
//判斷沙盒某路徑下是否存在數(shù)據(jù)文件
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = [self getFilePath:@"movie.plist"];
BOOL isExists = [fileManager fileExistsAtPath:filePath];
if (isExists)
{
//文件存在,讀取
_selectedRowArr = [[NSMutableArray alloc]initWithContentsOfFile:filePath];
}
else
{
//文件不存在,初始化
_selectedRowArr = [[NSMutableArray alloc]init];
}
//2.創(chuàng)建表
UITableView *tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
tableView.rowHeight = 80;
[self.view addSubview:tableView];
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellId];
[tableView release];
}
#pragma mark - **************** 獲取路徑
- (NSString *)getFilePath:(NSString *)name
{
NSString *doc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSLog(@"%@",doc);
return [doc stringByAppendingString:name];
}
#pragma mark - **************** 收到通知,保存數(shù)據(jù)
- (void)saveData
{
NSString *filePath = [self getFilePath:@"movie.plist"];
[_selectedRowArr writeToFile:filePath atomically:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:@"star_half"];
for (NSNumber *number in _selectedRowArr)
{
if (indexPath.row == [number integerValue])
{
cell.imageView.image = [UIImage imageNamed:@"star_full"];
}
}
cell.textLabel.text = [_movieArr objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - **************** 點擊單元格
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//4.判斷當(dāng)前點擊的Cell索引是否在_selectedRowArr中
//兩種情況:
//1.在
//2.不在
BOOL isSelect = NO;
for (NSNumber *number in _selectedRowArr)
{
NSInteger selectedRow = [number integerValue];
if (selectedRow == indexPath.row)
{
//已經(jīng)被選中
isSelect = YES;
}
}
//1.找到當(dāng)前點擊的單元格
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSNumber *number = [NSNumber numberWithInteger:indexPath.row];
//被選中,取消選中
if (isSelect)
{
//2.改變單元格上的圖片
selectedCell.imageView.image = [UIImage imageNamed:@"star_half"];
//3.索引從數(shù)組中移除
[_selectedRowArr removeObject:number];
}
//未被選中
else
{
//2.改變單元格上的圖片
selectedCell.imageView.image = [UIImage imageNamed:@"star_full"];
//3.將選中的單元格索引存進(jìn)數(shù)組中
[_selectedRowArr addObject:number];
}
}
@end
三、對象序列化
項目:ObjectSerialization0412
NSUserDefaults/writeToFile不能直接存儲自定義類
結(jié)論:
數(shù)組/字典/字符串/NSData可以直接使用NSUserDefaults/writeToFile的方式將數(shù)據(jù)寫入沙盒,因為這些類都實現(xiàn)了NSCoding協(xié)議
將自定義類對象寫入沙盒的條件:
1.實現(xiàn)NSCoding協(xié)議
2.對象序列化
(一)序列化 方法1
序列化:
NSKeyedArchiver:編碼器
作用:將一個實現(xiàn)NSCoding協(xié)議的對象轉(zhuǎn)換為二進(jìn)制數(shù)據(jù)(NSData)
1.編碼
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:people];
2.寫入沙盒
[data writeToFile:[self getFilePath] atomically:YES];
反序列化:
NSKeyedUnarchiver:解碼器
1.讀取數(shù)據(jù)
NSData *data = [NSData dataWithContentsOfFile:[self getFilePath]];
2.解碼
People *people = [NSKeyedUnarchiver unarchiveObjectWithData:data];
(二)方法2
序列化:
1.創(chuàng)建容器NSMutableData,保存要編碼的對象
NSMutableData *mData = [[NSMutableData alloc]init];
2.創(chuàng)建序列化器,指定要編碼的對象容器
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:mData];
3.編碼
[archiver encodeObject:people forKey:@"p"];
4.結(jié)束編碼
[archiver finishEncoding];
5.寫入文件
[mData writeToFile:[self getFilePath] atomically:YES];
反序列化:
1.讀取數(shù)據(jù)
NSMutableData *mData = [[NSMutableData alloc]initWithContentsOfFile:[self getFilePath]];
2.創(chuàng)建編碼器
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:mData];
3.解碼
People *people = [unarchiver decodeObjectForKey:@"p"];
4.結(jié)束解碼
[unarchiver finishDecoding];
源碼:
@implementation People
#pragma mark - **************** 編碼(對People類對象內(nèi)的每一個屬性進(jìn)行編碼)
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInteger:_age forKey:@"age"];
}
#pragma mark - **************** 解碼
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self)
{
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
#pragma mark - **************** 重寫description方法,用于自定義對象的輸入內(nèi)容(NSLog輸出的內(nèi)容)
- (NSString *)description
{
return [NSString stringWithFormat:@"%@--%d",self.name,self.age];
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@",NSHomeDirectory());
People *people = [People new];
people.name = @"張三";
people.age = 30;
NSArray *array = @[people];
//不能直接存儲自定義類
//1.NSUserDefaults不行
// NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//①
// [defaults setObject:people forKey:@"p"];
//②
// [defaults setObject:array forKey:@"p"];
//2.writeToFile也不可以
// NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/array.plist"];
// [array writeToFile:path atomically:YES];
//結(jié)論:
//數(shù)組/字典/字符串/NSData可以直接使用NSUserDefaults/writeToFile的方式將數(shù)據(jù)寫入沙盒,因為這些類都實現(xiàn)了NSCoding協(xié)議
//將自定義類對象寫入沙盒的條件:
//1.實現(xiàn)NSCoding協(xié)議
//2.對象序列化:
}
//對象序列化
- (IBAction)archiverClick:(UIButton *)sender
{
People *people = [People new];
people.name = @"張三";
people.age = 30;
//對象序列化:
//NSKeyedArchiver:編碼器
//作用:將一個實現(xiàn)NSCoding協(xié)議的對象轉(zhuǎn)換為二進(jìn)制數(shù)據(jù)(NSData)
//1.編碼
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:people];
//2.寫入沙盒
[data writeToFile:[self getFilePath] atomically:YES];
}
//對象反序列化
- (IBAction)unarchiverClick:(UIButton *)sender
{
//反序列化
//NSKeyedUnarchiver
//1.讀取
NSData *data = [NSData dataWithContentsOfFile:[self getFilePath]];
//2.對數(shù)據(jù)進(jìn)行解碼
People *people = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%@",people);
}
@end
項目:ObjectSerialization_Tow0412
#pragma mark - **************** 序列化
- (IBAction)archiverClick:(UIButton *)sender
{
People *people = [People new];
people.name = @"李四";
people.phoneNum = @"1234325423";
//1.創(chuàng)建一個NSMutableData,作為一個容器,保存要編碼的對象
NSMutableData *mData = [[NSMutableData alloc]init];
//2.創(chuàng)建序列化器,并且指定要編碼的對象保存的位置
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:mData];
//3.編碼
[archiver encodeObject:people forKey:@"p"];
//4.結(jié)束編碼
[archiver finishEncoding];
//5.寫入文件
BOOL is = [mData writeToFile:[self getFilePath] atomically:YES];
if (is)
{
NSLog(@"成功");
}
}
#pragma mark - **************** 反編碼
- (IBAction)unarchiverClick:(UIButton *)sender
{
//1.從沙盒中讀取數(shù)據(jù)
NSMutableData *mData = [[NSMutableData alloc]initWithContentsOfFile:[self getFilePath]];
//2.創(chuàng)建編碼器
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:mData];
//3.解碼
People *people = [unarchiver decodeObjectForKey:@"p"];
//4.結(jié)束解碼
[unarchiver finishDecoding];
NSLog(@"%@",people);
}
四、對容器類的拷貝
項目:FullyCopy0412
完全拷貝
方法1:
initWithArray:copyItems:對數(shù)組中的每一個元素調(diào)用 copy方法
條件:
1.元素實現(xiàn) NSCoping 協(xié)議
2.元素是可變對象
方法2:序列化
條件:數(shù)組/元素 必須實現(xiàn) NSCoding 協(xié)議
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
反序列化
NSArray *array4 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
源碼:
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//可變
NSString *text = @"12345";
// //不可變
// NSMutableString *text = [NSMutableString stringWithFormat:@"12345"];
NSArray *array = @[text];
// NSArray *array = @[mText];
NSArray *array1 = [array copy];//淺拷貝,拷貝指針
NSArray *array2 = [array mutableCopy];//深拷貝,拷貝對象
//完全拷貝:
//方法1:
//initWithArray: copyItems:對數(shù)組中的每一個元素調(diào)用 copy方法
//條件:
//1.元素實現(xiàn) NSCoping 協(xié)議
//2.元素是可變對象
NSArray *array3 = [[NSArray alloc]initWithArray:array copyItems:YES];
//方法2:序列化
//條件:數(shù)組/元素 必須實現(xiàn) NSCoding 協(xié)議
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
//反序列化
NSArray *array4 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
//輸出
NSLog(@"---%p---%p---%p---%p---%p",array,array1,array2,array3,array4);
//對于系統(tǒng)容器類來說,copy/mutableCopy,容器內(nèi)部的元素都是淺拷貝,
NSLog(@"===%p===%p===%p===%p===%p",array[0],array1[0],array2[0],array3[0],array4[0]);
}
@end