model : 1 .怎么来的 2: 放在哪 3: 怎么用是一个好的方式
数据本地化 : 1: 什么事沙河,沙河都有哪些文件夹,作用是什么.
2: 什么事数据本地化,什么时候使用
3: 如何把一个数组,字典,字符串,NSData放入本地
4: 如何把一个Person对象存入本地
NSFileManger NSFileHandle(了解就行) ;
沙盒机制
——————————————沙盒
沙盒 : 每个iOS应用程序都会为自己创建一个文件系统目录(文件夹),这个独立,封闭,安全的空间 ,叫做沙盒
注意: 1: 每一个应用程序都会拥有一个应用程序沙盒
2: 应用程序沙盒就是一个系统目录
独立: 不可能出现两个程序公用同一个沙盒
封闭 : 每一个沙盒 都只能他自己的应用去使用
安全 :沙盒 有被删除的失效
手动自动存入东西
——————————————文件夹
文件夹
- Documents : 1: 存入一些永远不被删除的文件(不会被系统主动删除),itunes备份时,同时也会备份Documents文件(条件: 尽量不在Documents放入音频视频等太大的东西,只放一些重要文件,以免审核被拒) 注 :可以存,有方法让什么
- Library : 1 Caches : 存储缓存的文件夹 当用户对某一个URL做请求操作的时候,这个URL里面的东西会保存在主机里面的某个位置 . Cookie 和Session . (itunes不会备份此目录,文件不会再应用退出时删除,一般存放比较大,不是特别重要的资源)
2: Preferences 保存应用的所有偏好设置.iOS的Settings(设置) 应用会该目录中查找应用的设置信息,iTunes会备份它, 注意: 不应该直接创建偏好设置文件,而是应该使用类来取得和设置应用程序的偏好
- tmp : 保存应用运行时所需的临时数据,使用完毕后会将相应的文件从该目录删除.应用没有运行时或者手机重启时 ,系统也有可能会清除该目录下的文件,iTunes 不会同步该目录
获取文件夹方法
- 第一种 : 通过该NSSeach搜索文件夹得地址,能获取Documents 和Library 内部文件夹地址, 但是不能获取tmp文件夹得地址,其他的都可以获取到.
//NSDocumentDirectory
表示获取
Documents
文件夹得地址
//NSLibraryDirectory / NSCachesDirectory
//NSUserDomainMask 表示用户的主目录
// 第三个参数表示 展开 "~" 的地址 , 设置为 YES 为完整路径
//NSSearchPathForDirectoriesInDomains 获取的是一个数组 (NSArray<NSString *> *), 数组只有一个元素 , 所以可以直接获取 objectAtIndex: 0 ;
NSString *documentPathStr = [ NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ) objectAtIndex :0];
//NSLibraryDirectory / NSCachesDirectory
//NSUserDomainMask 表示用户的主目录
// 第三个参数表示 展开 "~" 的地址 , 设置为 YES 为完整路径
//NSSearchPathForDirectoriesInDomains 获取的是一个数组 (NSArray<NSString *> *), 数组只有一个元素 , 所以可以直接获取 objectAtIndex: 0 ;
NSString *documentPathStr = [ NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ) objectAtIndex :0];
NSLog(@"%@",documentPathStr);
- 第二种 : 首先获取沙盒主路径的地址,然后拼接上想要去的文件夹的地址.
//
首先获取沙盒主路径的地址
NSString *homePathStr = NSHomeDirectory ();
NSLog ( @"homePathStr = %@" ,homePathStr);
// 其次 : 在沙盒主路径后拼接 Documents, 拼接出来 documents 文件夹的路径
NSString *documentsPathStr = [homePathStr stringByAppendingPathComponent : @"Library/Caches" ];
NSLog ( @"documents = %@" ,documentsPathStr);
// 获取 tmp 文件夹得路径
NSString *tmpPathStr = NSTemporaryDirectory ();
NSString *homePathStr = NSHomeDirectory ();
NSLog ( @"homePathStr = %@" ,homePathStr);
// 其次 : 在沙盒主路径后拼接 Documents, 拼接出来 documents 文件夹的路径
NSString *documentsPathStr = [homePathStr stringByAppendingPathComponent : @"Library/Caches" ];
NSLog ( @"documents = %@" ,documentsPathStr);
// 获取 tmp 文件夹得路径
NSString *tmpPathStr = NSTemporaryDirectory ();
NSLog(@"tmpPathStr = %@",tmpPathStr);
简单对象的写入与读写
——————————————数据本地化
把数据的,存储到应用程序的沙盒里面
- 写入
//1 .
要知道存到哪里
,So
需要一个文件夹的路径
NSString *documentsPathStr = [ NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ) objectAtIndex :0];
NSLog ( @"%@" ,documentsPathStr);
//2 . 知道要存什么 , 创建数据
NSString *str = @"hello world" ;
//3 . 要知道数据放哪里 , 创建一个路径 , 路径的终点局势存数据的文件 Component( 成分 )
NSString *strPath = [documentsPathStr stringByAppendingPathComponent : @"str.txt" ];
//4 . 写入操作
// atomically : YES 正当手机没电关机 会保存文件
// NO 否
// encoding : 编码方式
[str writeToFile :strPath atomically : YES encoding : NSUTF8StringEncoding error : nil ];
NSString *documentsPathStr = [ NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ) objectAtIndex :0];
NSLog ( @"%@" ,documentsPathStr);
//2 . 知道要存什么 , 创建数据
NSString *str = @"hello world" ;
//3 . 要知道数据放哪里 , 创建一个路径 , 路径的终点局势存数据的文件 Component( 成分 )
NSString *strPath = [documentsPathStr stringByAppendingPathComponent : @"str.txt" ];
//4 . 写入操作
// atomically : YES 正当手机没电关机 会保存文件
// NO 否
// encoding : 编码方式
[str writeToFile :strPath atomically : YES encoding : NSUTF8StringEncoding error : nil ];
- 读取
//通过路径读取数据,使用stringWithContentsOfFile方法,在读取的时候,第一个参数表示读取文件的路径,第二个参数表示编码格式,第三个表示错误信息.
NSString *newStr = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
——————————————NSData
/*
根据 imageName 获取图片 : 会在缓存里存一份 , 下次在获取同名图片 , 直接从缓存里取 . 优点 : 快 , 只有第一次的时候慢 , 但是之后再获取的话会很快 . 缺点 : 会浪费内存 , 如果只用致辞的话这块内存就浪费掉了 .
根据 ContentsOfFile 获取到的图片 : 每次都会根据路径去取图片 , 不会占用内存 . 如果图片只使用一次 , 推荐使用 ContentsOfFile
UIImage *image1 = [UIImage imageNamed:<#(nonnull NSString *)#>];
UIImage *image2 = [UIImage alloc]initWithContentsOfFile:<#(nonnull NSString *)#>];
123.png
123@2x.png
123@3x.png
根据 imageName 获取图片 : 会在缓存里存一份 , 下次在获取同名图片 , 直接从缓存里取 . 优点 : 快 , 只有第一次的时候慢 , 但是之后再获取的话会很快 . 缺点 : 会浪费内存 , 如果只用致辞的话这块内存就浪费掉了 .
根据 ContentsOfFile 获取到的图片 : 每次都会根据路径去取图片 , 不会占用内存 . 如果图片只使用一次 , 推荐使用 ContentsOfFile
UIImage *image1 = [UIImage imageNamed:<#(nonnull NSString *)#>];
UIImage *image2 = [UIImage alloc]initWithContentsOfFile:<#(nonnull NSString *)#>];
123.png
123@2x.png
123@3x.png
2x和3x,表示分辨率区别
// png
类型图片
,
只写名字就行了
写全
png
类型就指定了
*/
- 写入
//1
NSString
*documentPathStr = [
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
objectAtIndex
:0];
//2
UIImage
*image = [
UIImage
imageNamed
:
@"123"
];
//将UIImage类型对象转化成NSData类型的
//
第一个参数
:
转哪个
UIImage
类型对象
//第二个参数:压缩系数,越小压缩越厉害
NSData
*data =
UIImageJPEGRepresentation
(image, 1);
//3
NSString
*stringPath = [documentPathStr
stringByAppendingPathComponent
:
@"stringPath.txt"
];
//4
[data
writeToFile
:stringPath
atomically
:
YES
];
- 读取数据
NSData
*newData = [
NSData
dataWithContentsOfFile
:stringPath];
UIImage *newImage = [ UIImage imageWithData :newData];
UIImageView *newImageView = [[ UIImageView alloc ] initWithImage :newImage];
UIImage *newImage = [ UIImage imageWithData :newData];
UIImageView *newImageView = [[ UIImageView alloc ] initWithImage :newImage];
[self.view addSubview:newImageView];
复杂对象的写入与读取
什么是复杂对象?
在Foundation框架内不存在的数据类,如自定义Person类等 无法在程序内通过writeToFile: 这个方法写入文件内
只能通过将负载对象转化为NSData,即归档
——————————————归解档
#import
<Foundation/Foundation.h>
//
如果一个对象向直接写入本地
,
那么这个对象需要遵守
NSCoding
协议
@interface
Person :
NSObject
<
NSCoding
>
@property ( nonatomic , copy ) NSString * name;
@property ( nonatomic , copy ) NSString * gender;
@property ( nonatomic , assign ) NSUInteger age;
//nonatomic assign copy atomic weak strong readonly readwrite writeonly nonnull nullable retain unsafe_unretained
//_+ 属性名 命名的成员变量
//
@property ( nonatomic , copy ) NSString * name;
@property ( nonatomic , copy ) NSString * gender;
@property ( nonatomic , assign ) NSUInteger age;
//nonatomic assign copy atomic weak strong readonly readwrite writeonly nonnull nullable retain unsafe_unretained
//_+ 属性名 命名的成员变量
//
@end
#import
"Person.h"
@implementation Person
// 归档
// 在归档和解档的时候 , 要把所有的属性都进行归解档
-( void )encodeWithCoder:( NSCoder *)aCoder{
[aCoder encodeObject : self . name forKey : @"name" ];
[aCoder encodeObject : self . gender forKey : @"gender" ];
[aCoder encodeInteger : self . age forKey : @"age" ];
}
// 解档
-( instancetype )initWithCoder:( NSCoder *)aDecoder{
if ( self = [ super init ]) {
self . name = [aDecoder decodeObjectForKey : @"name" ];
self . gender = [aDecoder decodeObjectForKey : @"gender" ];
self . age = [aDecoder decodeIntegerForKey : @"age" ];
}
return self ;
}
@implementation Person
// 归档
// 在归档和解档的时候 , 要把所有的属性都进行归解档
-( void )encodeWithCoder:( NSCoder *)aCoder{
[aCoder encodeObject : self . name forKey : @"name" ];
[aCoder encodeObject : self . gender forKey : @"gender" ];
[aCoder encodeInteger : self . age forKey : @"age" ];
}
// 解档
-( instancetype )initWithCoder:( NSCoder *)aDecoder{
if ( self = [ super init ]) {
self . name = [aDecoder decodeObjectForKey : @"name" ];
self . gender = [aDecoder decodeObjectForKey : @"gender" ];
self . age = [aDecoder decodeIntegerForKey : @"age" ];
}
return self ;
}
@end
#import
"ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- ( void )viewDidLoad {
[ super viewDidLoad ];
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- ( void )viewDidLoad {
[ super viewDidLoad ];
// 如果一个对象向直接写入本地,那么这个对象需要遵守NSCoding协议
Person
*person = [[
Person
alloc
]
init
];
person. name = @" 男 " ;
person. gender = @" 男 " ;
person. age = 38 ;
#pragma mark ------ 归档
// 将复杂对象归档之后存入本地
person. name = @" 男 " ;
person. gender = @" 男 " ;
person. age = 38 ;
#pragma mark ------ 归档
// 将复杂对象归档之后存入本地
//第 1 步: 创建一个NSMutableData ,用于保存归档后的对象(初始化归档工具)
NSMutableData
*data = [
NSMutableData
data
];
//
第
2
步
:
创建个归档工具
NSKeyedArchiver *keyedArchiver = [[ NSKeyedArchiver alloc ] initForWritingWithMutableData :data];
NSKeyedArchiver *keyedArchiver = [[ NSKeyedArchiver alloc ] initForWritingWithMutableData :data];
//第 3 步: 归档
[keyedArchiver
encodeObject
:person
forKey
:
@"person"
];
//第 4 步: 结束归档
[keyedArchiver
finishEncoding
];
//这时候才Data存储好数据
NSLog(@"data = %@",data);
//获取,拼接写入沙盒路径
NSString
*documentPathStr = [
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
objectAtIndex
:0];
NSString
*dataPath = [documentPathStr
stringByAppendingPathComponent
:
@"person.plist"
] ;
//x写入
[data
writeToFile
:dataPath
atomically
:
YES
];
#pragma mark -------- 解档并使用
// 第 1 步 : 从本地获取到 Data
NSData *newData = [ NSData dataWithContentsOfFile :dataPath];
NSLog ( @"%@" ,newData);
// 第 2 步 : 通过获取到的 data 创建一个解档工具
NSKeyedUnarchiver *keyedUnarchiver = [[ NSKeyedUnarchiver alloc ] initForReadingWithData :newData];
// 第 3 步 : 创建一个 Person 对象 , 接收解档结果
Person *newPerson = [keyedUnarchiver decodeObjectForKey : @"person" ];
// 第 4 步 : 结束解档
[keyedUnarchiver finishDecoding ];
//
NSLog ( @"%@" ,newPerson);
// 归解档是一种编码方式 , 不是数据本地化的方式
// 负载对象写入本地实际上使用的还是 writeToFile 的简单写入本地的方法
// 整存整取 writeToFile
#pragma mark -------- 解档并使用
// 第 1 步 : 从本地获取到 Data
NSData *newData = [ NSData dataWithContentsOfFile :dataPath];
NSLog ( @"%@" ,newData);
// 第 2 步 : 通过获取到的 data 创建一个解档工具
NSKeyedUnarchiver *keyedUnarchiver = [[ NSKeyedUnarchiver alloc ] initForReadingWithData :newData];
// 第 3 步 : 创建一个 Person 对象 , 接收解档结果
Person *newPerson = [keyedUnarchiver decodeObjectForKey : @"person" ];
// 第 4 步 : 结束解档
[keyedUnarchiver finishDecoding ];
//
NSLog ( @"%@" ,newPerson);
// 归解档是一种编码方式 , 不是数据本地化的方式
// 负载对象写入本地实际上使用的还是 writeToFile 的简单写入本地的方法
// 整存整取 writeToFile
//在一个路径下存数据,最后一次存进去的东西会覆盖之前的
总结
- 简单对象写入文件过程:
- 创建字符串获取存储文件的文件夹路径
- 创建需要存储的数据
- 创建字符串通过拼接创建并获得存储文件的路径
- 写入 writeToFile
- 读取: 通过路径读取数据,使用stringWithContentsOfFile方法
- 归档:
- 创建对象 (并设置属性)
- 遵循NSCoding协议,并实现方法
- 创建实例对象
- 创建NSData用来存储对象并初始化归档工具
- 创建归档工具
- 归档
- 结束归档
- 获取,拼接沙盒文件路径
- 写入
- 解档
- 获取沙盒文件路径
- 创建NSData,并接收本地数据
- 创建解档工具,通过NSData
- 创建对象,并接收解档结果
- 结束解档
- 什么类型的对象可以直接存入本地?
- NSString(在写入本地和读取时,都需要进行UTF8转码)
- NSArray
- NSDictionary
- NSData {
- NSData如何转出UIImage : imageWithData:NSData
- UIImage如果转成NSData : UIImageJPEGRepresentation(UIImage *, CGFloat);
}
- 存入本地的过程?
1.找到存储的路径
2.创建要存储的数据
3.创建存储数据的内容
4.存储数据
数据本地化的方式 :
- 直接写入本地
- sqlite
- CoreData
- NSUserDefaultes(属性列表,并不是数据本地化的一个方式,但是可以达成数据本地化)
归解档
- 传值的方式:
- block
- 代理
- 属性
- 单例
- 通知中心
- 数据本地化
- 设计模式(实现方式)
- 单例
- 代理
- Target-Action
- 通知中心
MVC:框架的设计方式
任务
//通讯录 添加和删除 联系人时 下次打开有变化
documents(n.文档)
Directory(
n. [计] 目录;)
Domain(
n. 领域;域名;
)
Component(
n. 成分;组件;
)
Representation(
n. 代表;表现)
encode(
vt. (将文字材料)译成密码;编码,
)
decode(
vt. [计][通信] 译码,解码
)
ćīŚǂvş