IOS笔记048-数据存储

?

IOS数据存储的几种方式

? ? ? ? XML属性列表(plist)

? ? ? ??归档 Preference(偏好设置)?

? ? ? ??NSKeyedArchiver归档(NSCoding)

? ? ? ? SQLite3

? ? ? ??Core Data

先来研究一下前三种。

? ? ? ? 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离。应用必须待在自己的沙盒里,其他应用不能访问该沙盒。沙盒的结构如下所示:

? ? ? ?应用程序包:(上图中的QQ.app)包含了所有的资源文件和可执行文件。
? ? ? ?Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录。
? ? ? ?tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录。
? ? ? ?Library/Caches:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据。
? ? ? ?Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录。

每个目录的获取方法

? ? ? ? ? ?//?临时目录

? ? ? ? ? ??NSString?*path =?NSTemporaryDirectory();

? ? ? ? ? ??// /Users/song/Library/Developer/CoreSimulator/Devices/B040D34E-CF0E-41C2-9BD0-C309566CC349/data/Containers/Data/Application/A8519BA5-FB34-4B31-BB72-3948264AFB37/tmp/

? ? ? ? ? ??//?主目录

? ? ? ? ? ??NSString?*path = NSHomeDirectory();

? ? ? ? ? ??//? /Users/song/Library/Developer/CoreSimulator/Devices/B040D34E-CF0E-41C2-9BD0-C309566CC349/data/Containers/Data/Application/E6A8A443-55CA-463B-886C-DAAF69E8F3BC

?? ? ? ? ? ?

? ? ? ? ? ??// Documents?目录,第三个参数为yes显示全路径,为NO时显示位波浪线 “~”

? ? ? ? ? ??NSString?*path1 =?NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,?NSUserDomainMask,?YES)[0];

? ? ? ? ? ??// /Users/song/Library/Developer/CoreSimulator/Devices/B040D34E-CF0E-41C2-9BD0-C309566CC349/data/Containers/Data/Application/61B033AA-BBFB-4A3A-AD6E-2E332B78C2ED/Documents

? ? ? ? ? ??NSString?*path1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,?NO)[0];

? ? ? ? ? ??//? ~/Documents

? ? ? ? ? ??// cache?目录

? ? ? ? ? ??NSString?*path2 =NSSearchPathForDirectoriesInDomains(NSCachesDirectory,?NSUserDomainMask,?YES)[0];

? ? ? ? ? ??// /Users/song/Library/Developer/CoreSimulator/Devices/B040D34E-CF0E-41C2-9BD0-C309566CC349/data/Containers/Data/Application/1B4923AF-4B1F-4C7A-941E-D3621D7945C3/Library/Caches

? ? ? ? ? ??// PreferencePanes?目录

? ? ? ? ? ??NSString?*path2 =NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask,?YES)[0];

? ? ? ? ? ??// /Users/song/Library/Developer/CoreSimulator/Devices/B040D34E-CF0E-41C2-9BD0-C309566CC349/data/Containers/Data/Application/D654173E-DC23-4951-8C28-016878B5246B/Library/PreferencePanes

还有一个特殊的单例对象用来保存用户设置

? ? ? ? ? ??//?默认保存到PreferencePanes目录

? ? ? ? ? ? [[NSUserDefaults?standardUserDefaults]?setObject:@“hah”?forKey:@"1"];

? ? ? ? ? ? [[NSUserDefaults?standardUserDefaults]?setBool:YES?forKey:@“2”];

1、plist文件

? ? ? ? 属性列表是一种XML格式的文件,拓展名为plist

? ? ? ??如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中.

? ? ? ? 保存数据

? ? ? ? ? ??// plist保存数据

? ? ? ? ? ??//?保存用户名、密码、记住密码、自动登录

? ? ? ? ? ??NSMutableDictionary?*dict = [NSMutableDictionarydictionary];

? ? ? ? ? ? [dict?setObject:_userField.text?forKey:@"user"];

? ? ? ? ? ? [dict?setObject:_pwdField.text?forKey:@"pwd"];

? ? ? ? ? ? [dict?setObject:@(_rmbPwdSwitch.on)?forKey:@"rmb"];

? ? ? ? ? ? [dict?setObject:@(_autoLoginSwitch.on)?forKey:@"auto"];

? ? ? ? ? ??//?获取cache路径

? ? ? ? ? ??NSString?*cachePath =?NSSearchPathForDirectoriesInDomains(NSCachesDirectory,?NSUserDomainMask,?YES)[0];

? ? ? ? ? ??//?取得文件的全路径

? ? ? ? ? ??NSString?*filePath = [cachePath?stringByAppendingPathComponent:@"userInfo.plist"];

? ? ? ? ? ??//?写入到文件

? ? ? ? ? ? [dict?writeToFile:filePath?atomically:YES];

?

? ? ? ?读取数据

? ??//?读取plist中数据,显示在textField中

? ??//?获取cache路径

? ??NSString?*cachePath =?NSSearchPathForDirectoriesInDomains(NSCachesDirectory,?NSUserDomainMask,?YES)[0];

? ??//?取得文件的全路径

? ??NSString?*filePath = [cachePath?stringByAppendingPathComponent:@"userInfo.plist"];

? ??//?读取字典数据

? ??NSDictionary?*dict = [NSDictionary?dictionaryWithContentsOfFile:filePath];

? ??//?给控件赋值

? ??NSString?*userName = dict[@"user"];

? ??NSString?*pwd? = dict[@"pwd"];

? ??BOOL?rmb =? dict[@"rmb"];

? ??BOOL?autoLogin = dict[@"autoLogin"];

?? ?

? ??_userField.text?= userName;

?? ?

? ??if?(rmb ==?YES)

? ? {

? ? ? ??_pwdField.text?= pwd;

? ? }

?

? ??_rmbPwdSwitch.on?= rmb;

? ??_autoLoginSwitch.on?= autoLogin;

这里目前还有问题,那就是读取出来的bool变量全是YES。等明天研究一下再。

?问题出来了,读取字典中得bool变量时要转换一下

? ??//?给控件赋值

? ??NSString?*userName = dict[@"user"];

? ??NSString?*pwd? = dict[@"pwd"];

? ??BOOL?rmbPwd =? [dict[@"rmb"]?boolValue];?//?要转换一下,不然读取结果不准确

? ??BOOL?login = [dict[@"autoLogin"]?boolValue];

2、Preference 偏好设置

内部实现也是一个plist文件。不过是否系统控制路径和名称。只需写入和读取就行,不用关系细节。

写入数据

? ? ? ? ? ??// preference?偏好设置

? ? ? ? ? ? ?NSUserDefaults?*userDefault = [NSUserDefaults?standardUserDefaults];?//?单例对象

? ? ? ? ? ? [userDefault?setObject:_userField.text?forKey:@"user"];

? ? ? ? ? ? [userDefault?setObject:_pwdField.text?forKey:@"pwd"];

? ? ? ? ? ? [userDefault?setBool:_rmbPwdSwitch.on?forKey:@"rmb"];

? ? ? ? ? ? [userDefault?setBool:_autoLoginSwitch.on?forKey:@"autoLogin"];

?读取数据

? ??//?偏好设置,读取数据,

? ??NSUserDefaults?*userDefault = [NSUserDefaults?standardUserDefaults];

? ??NSString?*name = [userDefault?stringForKey:@"user"];

? ??NSString?*pwd = [userDefault?stringForKey:@"pwd"];

? ??BOOL?rmbPwd = [[userDefault?boolForKey:@“rmb”] boolValue];

? ??BOOL?login = [[userDefault?boolForKey:@“autoLogin”] boolValue];

? ??//?给控件赋值

? ??_userField.text?= name;

? ??if?(rmbPwd ==?YES)

? ? {

? ? ? ??_pwdField.text?= pwd;?//?记住密码才赋值

? ? }

? ??_rmbPwdSwitch.on?= rmbPwd;

? ??_autoLoginSwitch.on?= login;

? ??if?(login) {?//?自动登录

?? ? ? ?

? ? ? ? [self?login:nil];

? ? }

注意:UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法强制写入
[defaults synchornize];

?3、NSKeyedArchiver 归档

如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复
不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以
NSCoding协议有2个方法:
? ? ? ??encodeWithCoder:
每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量
? ? ? ??initWithCoder:
每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量。

? ? 1、常见类型

写入常用类型

? ? ? ? ? ??//?归档对象NSKeyedArchiver

? ? ? ? ? ??//?获取路径

? ? ? ? ? ??NSString?*cachePath =?NSSearchPathForDirectoriesInDomains(NSCachesDirectory,?NSUserDomainMask,?YES)[0];

? ? ? ? ? ??//?取得文件的全路径

? ? ? ? ? ??NSString?*filePath = [cachePath?stringByAppendingPathComponent:@"info.data"];

?? ? ? ? ? ?

//? ? ? ? ? ? [NSKeyedArchiver archiveRootObject:_userField.text toFile:filePath];

? ? ? ? ? ??NSArray?*all =?@[_userField.text,_pwdField.text,@(_rmbPwdSwitch.on),@(_autoLoginSwitch.on)];

? ? ? ? ? ? [NSKeyedArchiver?archiveRootObject:all?toFile:filePath];

读取

? ??//?获取路径

? ??NSString?*cachePath =?NSSearchPathForDirectoriesInDomains(NSCachesDirectory,?NSUserDomainMask,?YES)[0];

? ??//?取得文件的全路径

? ??NSString?*filePath = [cachePath?stringByAppendingPathComponent:@"info.data"];

? ??//?归档对象NSKeyedArchiver

//? ? NSString *name =? [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

? ??NSArray?*all = [NSKeyedUnarchiver?unarchiveObjectWithFile:filePath];

? ??NSLog(@"%@",all);

? ? 2、自定义对象

?要读写自定义对象,自定义对象要遵守NSCoding协议,并实现两个方法,一个打包initWithCoder:,一个解包encodeWithCoder:

?以联系人为例

? ??#import?<Foundation/Foundation.h>

?

? ??@interface?SLQContact :?NSObject?<NSCoding>

?

? ??/*姓名*/

? ??@property?(strong,?nonatomic)?NSString?*name;

? ??//?手机号

? ??@property?(strong,?nonatomic)?NSString?*phone;

?

? ? + (instancetype)contactWithName:(NSString?*)name andPhone:(NSString?*)phone;

? ??@end

实现协议方法?

? ??#import?"SLQContact.h"

?

? ??@implementation?SLQContact

?

? ? + (instancetype)contactWithName:(NSString?*)name andPhone:(NSString?*)phone

? ? {

? ? ? ??SLQContact?*contact = [[self?alloc]?init];

? ? ? ? contact.name?= name;

? ? ? ? contact.phone?= phone;

? ? ? ??return? contact;

? ? }

? ??//?解包,按照key找属性

? ? - (void)encodeWithCoder:(NSCoder?*)aCoder

? ? {

? ? ? ? [aCoder?encodeObject:self.name?forKey:@"name"];

? ? ? ? [aCoder?encodeObject:self.phone?forKey:@"phone"];

? ? }

? ??//?打包,就是给属性指定一个key

? ? - (id)initWithCoder:(NSCoder?*)aDecoder

? ? {

? ? ? ??if?(self?= [super?init])

? ? ? ? {

? ? ? ? ? ??self.name?= [aDecoder?decodeObjectForKey:@"name"];

? ? ? ? ? ??self.phone?= [aDecoder?decodeObjectForKey:@"phone"];

? ? ? ? }

? ? ? ??return??self;

? ? }

? ??@end?

然后在联系人控制器中读写归档文件

定义一个宏用来获取文件路径

//?获得归档文件的路径

#define SLQFilePath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"info.data"]

写如归档文件

? ??//?添加按钮,按下后进入添加联系人界面

? ? - (IBAction)addBtn:(id)sender {

? ? ? ??//

? ??//? ? [self performSegueWithIdentifier:@"contactToAdd" sender:nil];

? ? ? ??//?通过代码获取storyboard中得控制器

? ? ? ??UIStoryboard?*story = [UIStoryboard?storyboardWithName:@"Main"?bundle:nil];

? ? ? ??//?获取main。storyboard中得控制器,以标识符区分

? ? ? ??SLQAddViewController* addVC = [story?instantiateViewControllerWithIdentifier:@"add"];

? ? ? ??// block封装待执行的代码

? ? ? ? addVC.block= ^(SLQContact?*contact){

? ? ? ? ? ??//?更新模型

? ? ? ? ? ? [self.contacts?addObject:contact];

? ? ? ? ? ??//?刷新表格

? ? ? ? ? ? [self.tableView?reloadData];

? ? ? ? ? ??// 3.保存联系人,注意:如果归档数组,底层会遍历数组元素一个一个归档

? ? ? ? ? ? [NSKeyedArchiverarchiveRootObject:self.contactstoFile:SLQFilePath];

? ? ? ? };

? ? ? ??//?跳转到添加联系人界面

? ? ? ? [self.navigationController?pushViewController:addVC?animated:YES];

? ??}?

?读取归档文件,在属性contacts的setter方法中进行读取。

? ??//?重写set方法

? ? - (NSMutableArray *)contacts

? ? {

? ? ? ??if?(_contacts ==?nil)

? ? ? ? {

? ? ? ? ? ??//?读取归档文件

? ? ? ? ? ? _contacts = [NSKeyedUnarchiver unarchiveObjectWithFile:SLQFilePath];

? ? ? ? ? ??if?(_contacts ==?nil) {?//?如果读取的文件为空,初始化数组

? ? ? ? ? ? ? ? ? _contacts = [NSMutableArray array];

? ? ? ? ? ? }

? ? ? ? }

? ? ? ??return?_contacts;

? ? }

?

还有两种存储方式,属于数据库范畴,继续学习。

?

?

时间: 2024-10-27 03:47:03

IOS笔记048-数据存储的相关文章

李洪强iOS开发之数据存储

李洪强iOS开发之数据存储 iOS应用数据存储的常用方式 1.lXML属性列表(plist)归档 2.lPreference(偏好设置) 3.lNSKeyedArchiver归档(NSCoding) 4.lSQLite3 5.lCore Data Documents: 保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录.例如,游戏应用可将游戏存档保存在该目录 tmp: 保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除.应用没有运行时,系统也可能会清除该目录

UI进阶--iOS中的数据存储常用方式

iOS中的数据存储常用方式: 1.xml属性列表(plist): 2.preference偏好设置; 3.NSKeyedArchiver归档(需要遵守NSCodeing协议); 4.SQLite 3; 5.Core Data; ...... 应用沙盒: 每个iOS应用都有?己的应?沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应?必须待在?己的沙盒里,其他应用不能访问该沙盒(提示:在IOS8中已经开放访问) 应?沙盒的文件系统?录,如下图所示(假设应用的名称叫Layer) 模拟器应?用沙

利用IOS模拟器将数据存储在本地沙盒中以及从沙盒中读取详细步骤

使用IO模拟器,应用沙盒的根路径为:/Users/apple/Library/Application Support/iPhone Simulator/6.0/Applications(6.0为模拟器的版本) 1.获取应用沙盒目录 <1>利用沙盒根目录拼接"Documents"字符串 NSString * home = NSHomeDirectory(); NSString * documents = [home stringByAppendingPathComponent

iOS中的数据存储

SQLite3 SQLite3是一款开源的嵌入式关系型数据库,可移植性好,易使用,内存开销小. SQLite3是无类型的,意味着你可以保存任何类型的数据到任意表的任意字段中. SQLite3常用的4种数据类型:text(文本字符串), integer(整型值), real(浮点值), blob(二进制数据(比如文件)). 在iOS中使用SQLite3,首先要添加库文件'libsqlite3.dylib'和导入主头文件#import<sqlite3.h> SQL语句的特点: 1> 不区分大

ios开发之数据存储

iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core Data 应用沙盒 每个iOS应用都有自己的应用沙盒(应用沙盒就是应用的文件夹),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒 应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer) 模拟器应用沙盒的根路径在: (apple是用户名, 6.0是模拟器版本)/Users/apple/Li

ios开发----应用数据存储的常用方法之plist存取方法

[注意]转载时请注明出处博客园-吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/ ios应用数据存储的常用方式主要有: XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core Data ios应用沙盒机制 介绍这些方法之前,首先介绍一下应用沙盒的概念. ios应用沙盒机制就是指ios应用程序只能在为该程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以

Android 学习笔记之数据存储SharePreferenced+File

学习内容: Android的数据存储.... 1.使用SharedPreferences来保存和读取数据... 2.使用File中的I/O来完成对数据的存储和读取...   一个应用程序,经常需要与用户之间形成交互...需要保存用户的设置和用户的数据信息...这些都离不开数据的存储...Android的数据采用五种方式来进行存储...在这里就先介绍两种存储方式... 1.使用SharedPreferences存储数据...   对于软件配置参数的保存,Windows系统采用ini文件来进行保存,

Android开发笔记之: 数据存储方式详解

无论是神马平台,神马开发环境,神马软件程序,数据都是核心.对于开发平台来讲,如果对数据的存储有良好的支持,那么对应用程序的开发将会有很大的促进作用.总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.其中文件和数据库可能用的稍多一些,文件用起来较为方便,程序可以自己定义格式:数据库用起稍烦锁一些,但它有它的优点,比如在海量数据时性能优越,有查询功能,可以加密,可以加锁,可以跨应用,跨平台等等:网络,则用于比较重要的事情,比如科研,勘探,航空等实时采集到的数据需要马上通过网络

iOS 四种数据存储方式

NSKeyedArchiver:采用归档的形式来保存数据,该数据对象需要 遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法.前一个方法告诉系统怎么对 对象进行编码,而后一个方法则是告诉系统怎么对对象进行解码.例如对Possession对象归档保存. NSUserDefaults:用来保存应用程序设置和属性.用户保存的数 据.用户再次打开程序或开机后这些数据仍然存在.NSUserDefaults可以存储的数据类型包括:NSDat