Android和iOS上的html5 本地存储储有多久

没有更多推荐了,
不良信息举报
举报内容:
iOS开发中本地数据存储的总结
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!IOS-本地存储-NSUserDefaults - 简书
IOS-本地存储-NSUserDefaults
IOS-本地存储-NSUserDefaults
一 NSUserDefaults简介
NSUserDefaults类提供了一个与默认系统进行交互的编程接口。NSUserD efaults对象是用来保存、恢复应用程序相关的偏好设置、配置数据等等。默认系统允许应用程序自定义它的行为去迎合用户的喜好。你可以在程序运行的时候从用户默认的数据库中读取程序的设置,同时NSUserDefaults的缓存避免了在每次读取数据时候都打开用户默认数据库的操作。可以通过调用synchroni ze方法来使内存中的缓存与用户默认系统进行同步。NSUserDefaults类提供了非常方便的方法来读写常用的类型,常用的方法有:setBool:forKey、setFloat :forKey、setInteger:forKey、setObject:forKey、setDouble:forKey、setURL:forKey,具体使用哪个方法取决于要存储的数据类型。其中,方法setObject: forKey用于存储NSString、NSDate、NSArry、NSDictionary等复合对象类型。
二 实例代码
NSUserDefaults是单例,同时也是线程安全的。使用方法如下:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults
setBool: self.toggleSwitch.on forKey:kOnOffToggle];
[userDefaults setFloat: self.brightnessSlider.value forKey:kBrightnessLevel];
注意:上述代码将数据写入默认设置数据库时,并不一定会立即保存这些数据。还需要进一步调用 synchronize 方法确保所有数据都及时写入:
[userDefaultssynchronize];
要将这些数据读入 App 中,可根据键值和返回类型,调用相应的方法。根据要读取的数据类型,可选择 arrayForKey、boolForKey、dateforKey、 dictionaryForKey、 floatForKey、integerForKey、objectForKey、doubleForKey和URLForKey等方法。
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.brightnessSlider.value = [userDefaults floatForKey:kBrightnessLevel];
self.toggleSwitch.on = [userDefaults boolForKey:kOnOffToggle];
NSUserDefaults适合存储轻量级的本地数据,比如要保存一个登陆界面的数据,用户名、密码之类的,个人觉得使用NSUserDefaults是首选。下次再登陆的时候就可以直接从NSUserDefaults里面读取上次登陆的信息。
因为如果使用自己建立的plist文件什么的,还得自己显示创建文件,读取文件,很麻烦,而是用NSUserDefaults则不用管这些东西,就像读字符串一样,直接读取就可以了(NSUserDefaults中的数据最终都会存储到plist属性列表里面)。NSUserDefaults支持的数据格式有:NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL类型。
NSUserDefaults很方便,读取也很容易。下面给出一个示例看看如何使用,ViewController.h文件中主要是放几个控件,用于显示存储的数据:
#import &UIKit/UIKit.h&
@interface ViewController : UIViewController
IBOutlet UILabel *txtI
IBOutlet UILabel *txtF
IBOutlet UILabel *txtD
IBOutlet UILabel *txtNSS
IBOutlet UILabel *txtNSD
IBOutlet UILabel *txtNSA
IBOutlet UILabel *txtNSD
ViewController.m文件中最重要的是两个方法:
saveNSUserDefaults:用于将各种类型数据保存到NSUserDefaults中
readNSUserDefautls:用于从NSUserDefaults中读取各种类型的数据。在viewDidLoad中调用这两个方法就可以看出结果咯
#import "ViewController.h"
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
[self saveNSUserDefaults];
//调用此方法将各种数据存储到NSUserDefautls中,在下面定义
[self readNSUserDefaults];
//调用此方法从NSUserDefautls中读取各种数据,在下面定义
- (void)viewDidUnload
[txtNSString release];
txtNSString =
[txtNSDate release];
txtNSDate =
[txtNSArray release];
txtNSArray =
[txtNSDictionary release];
txtNSDictionary =
[txtInteger release];
txtInteger =
[txtFloat release];
txtFloat =
[txtDouble release];
txtDouble =
[super viewDidUnload];
// Release any retained subviews of the main view.
//保存数据到NSUserDefaults
-(void)saveNSUserDefaults
NSString *myString = @"enuola";
int myInteger = 100;
float myFloat = 50.0f;
double myDouble = 20.0;
NSDate *myDate = [NSDate date];
NSArray *myArray = [NSArray arrayWithObjects:@"hello", @"world", nil];
NSDictionary *myDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"enuo", @"20", nil] forKeys:[NSArray arrayWithObjects:@"name", @"age", nil]];
//将上述数据全部存储到NSUserDefaults中
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//存储时,除NSNumber类型使用对应的类型意外,其他的都是使用setObject:forKey:
[userDefaults setInteger:myInteger forKey:@"myInteger"];
[userDefaults setFloat:myFloat forKey:@"myFloat"];
[userDefaults setDouble:myDouble forKey:@"myDouble"];
[userDefaults setObject:myString forKey:@"myString"];
[userDefaults setObject:myDate forKey:@"myDate"];
[userDefaults setObject:myArray forKey:@"myArray"];
[userDefaults setObject:myDictionary forKey:@"myDictionary"];
//这里建议同步存储到磁盘中,但是不是必须的
[userDefaults synchronize];
//从NSUserDefaults中读取数据
-(void)readNSUserDefaults
NSUserDefaults *userDefaultes = [NSUserDefaults standardUserDefaults];
//读取数据到各个label中
//读取整型int类型的数据
NSInteger myInteger = [userDefaultes integerForKey:@"myInteger"];
txtInteger.text = [NSString stringWithFormat:@"%d",myInteger];
//读取浮点型float类型的数据
float myFloat = [userDefaultes floatForKey:@"myFloat"];
txtFloat.text = [NSString stringWithFormat:@"%f",myFloat];
//读取double类型的数据
double myDouble = [userDefaultes doubleForKey:@"myDouble"];
txtDouble.text = [NSString stringWithFormat:@"%f",myDouble];
//读取NSString类型的数据
NSString *myString = [userDefaultes stringForKey:@"myString"];
txtNSString.text = myS
//读取NSDate日期类型的数据
NSDate *myDate = [userDefaultes valueForKey:@"myDate"];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
txtNSDate.text = [NSString stringWithFormat:@"%@",[df stringFromDate:myDate]];
//读取数组NSArray类型的数据
NSArray *myArray = [userDefaultes arrayForKey:@"myArray"];
NSString *myArrayString = [[NSString alloc] init];
for(NSString *str in myArray)
NSLog(@"str= %@",str);
myArrayString = [NSString stringWithFormat:@"%@
%@", myArrayString, str];
[myArrayString stringByAppendingString:str];
[myArrayString stringByAppendingFormat:@"%@",str];
NSLog(@"myArrayString=%@",myArrayString);
txtNSArray.text = myArrayS
//读取字典类型NSDictionary类型的数据
NSDictionary *myDictionary = [userDefaultes dictionaryForKey:@"myDictionary"];
NSString *myDicString = [NSString stringWithFormat:@"name:%@, age:%d",
[myDictionary valueForKey:@"name"], [[myDictionary valueForKey:@"age"] integerValue]];
txtNSDictionary.text = myDicS
好了,运行一下,可以看到xib文件中的各种数据已经绑定上了吧?
再次运行的时候,可以把viewDidLoad中的
saveNSUserDefaults];
这一行注释掉,让程序直接读取而不存储数据,发现以前保存的数据仍然可以读取到界面上。
用NSUserDefaults存储的数据下次程序运行的时候依然存在,它把数据存储在什么地方了?如何能够清除?其实它存储在应用程序内置的一个plist文件里,这个可以根据路径看到。比如说这个是你的程序沙盒位置: /Users/Library/Application Support/iPhoneSimulator/4.1/Applicati*****/29788E40-AF47-45A0-8E92-3AC0F501B7F4/,(这个是应用程序对应在mac上的位置)这个下面有/Library/Prefereces,里面有个plist文件,存储的就是你的userDefaults想要删掉的话,用removeObjectForKey或者删掉沙盒,也就是你的应用程序然后重新安装。
三 注意问题
1、UserDefaults是根据时间戳定时的把缓存中的数据写入本地磁盘,而非即时写入。为了防止数据丢失,我们在对重要的数据保存时使用synchornize方法强制写入。但是也要注意,不用频繁的使用synchornize,这样毕竟影响性能和效率,
2、IOS本地存储位置说明
&Application_Home&/Documents/
您应该将所有的应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。有关如何取得这个目录路径的信息,请参见“获取应用程序目录的路径”部分。iTunes会备份这个目录的内容。
&Application_Home&/Library/Preferences
这个目录包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类或CFPreferences API来取得和设置应用程序的偏好,详情请参见“添加Settings程序包”部分。iTunes会备份这个目录的内容。
有时候,在乎得太多,对自己而言也是一种折磨。
1、NSUserDefault——官方文档 NSUserDefaults类提供了访问常见类型(如float,double,int,bool和URL)的便捷方法。一个默认对象必须是一个属性列表 - 也就是,一个实例(或集合,实例的组合):NSData,NSString,NSN...
*面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把基础的东西弄好,复杂的东西了解就ok了! *此题库是年北上广深杭各大小公司面试题。 *注:如今社会还是得靠本事,面试题60分只是多了一个机会,...
转载自:http://www.mamicode.com/info-detail-957988.html 1、iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite...
前言 持久化方案不管是服务端还是客户端,都是一个非常值得讨论的话题。尤其是在服务端,持久化方案的优劣往往都会在一定程度上影响到产品的性能。然而在客户端,只有为数不多的业务需求会涉及持久化方案,而且在大多数情况下,持久化方案对性能的要求并不是特别苛刻。所以我在移动端这边做持久...
关于首选项和设置 首选项是您持久存储的信息,并用于配置您的应用程序。应用程序通常会向用户公开偏好设置,以便他们自定义应用程序的外观和行为。大多数首选项都使用Cocoa首选项系统(称为用户默认系统)本地存储。应用程序还可以使用键值存储在用户的iCloud帐户中存储首选项。 用...
凌晨三点的时候,睡眼惺忪的我接到了小北打来的电话。她急急忙忙的告诉我:“汪洋明天要结婚了,你知道吗?”我抬眼看了看手机,苦笑着说:“瞎说什么啊,现在已经凌晨三点了,是今天,今天他结婚!”我随手将手机扔了很远,脑袋里的瞌睡虫猛得被赶走。 是的,汪洋今天要结婚了。 我的前男友要...
上一节曾今提到过LiveData是生命周期感知组件的示例。与ViewModel一起使用LiveData可以在遵循Android生命周期的情况下,更容易地使用数据填充UI。那么什么是LiveData?根据谷歌官方解释,LiveData是一个数据持有者类,它保持一个值,并允许观...
出轨似乎是婚姻生活里抹不掉的阴影,有的人选择了出轨,有的人选择了重生,有的人选择了将出轨的心深深埋藏。 有人说,年轻时我们不懂爱,我的婚姻生活缺乏激情,我们夫妻生活越来越不合拍,我们不在一个频道上了,婚后的他(她)离我越来越远,我们只有生活的鸡零狗碎,再没了爱情。N个出轨的...
壹 “马上就要送材料进窗口了,快点做好!还有两个小时,就要闭窗口了,你要在两个小时内做好!” “这个材料还是不行,你再做一份来,八点之前我就要,唔,现在六点半,还一个半小时,你应该能搞好吧!” “领导,现在到截止时间了才说还差材料,我实在赶不及了!” “那叫某某们帮你加快速...没有更多推荐了,
不良信息举报
举报内容:
Android存储和加载本地文件(内部存储设备)
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!理一下iOS本地持久化储存(侧重数据库SQLite)
招聘信息:
本文是投稿文章,作者:Toyun()公司的项目存在已有两年,版本也到三点几了,但是本地持久化数据存储,始终用的是GVUserDefaults这个对NSUserDefaults进行了扩展的第三方库。但随着业务的发展,需要存储的地方越来越多,GVUserDefaults也越来也不能适应需求,当我们都忍受不了的时候,经过一番商讨之后,决定使用FMDB这个封装了SQLite3的第三方库。此篇文章以此为主线,理一理数据库和本地化储存的一些知识,但是此篇文章丝毫没有提到CoreData,喜欢使用CoreData的同学,这里先说声对不起了浪费了您20s宝贵的时间。此篇文章的逻辑如下图所示:图0-0 此篇文章的逻辑图iOS本地持久化储存方式概述说起iOS本地化储存的方式,大家估计在也熟悉不过了,NSUserDefault、File,Keychain、DataBase无非也就这几种方式。NSUserDefault、File:这两种使用方式都很简单,需要注意的一点就是所存储的对象都需要遵守并实现NSCoding协议中的两个方法,适用的范围也都是一些小规模数据,其实NSUserDefault的底层实现还是以.plist文件进行储存的。Keychain:用于储存一些私密信息,比如密码、证书等等,Keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效。同样也适用于应用之间数据共享。DataBase:说到储存,就不能不提DataBase技术,移动端所用的DBMS一般都是SQLite3,在iOS下,SQLite3的API是纯C语言的,这样我们一直以来面向对象开发的朋友们,突然找不到了对象,有点那么的惊慌失措。好在开源社区出现了像FMDB这样优秀的第三方框架帮我们找回了对象,同样苹果自己也出了新的技术就是所谓的CoreData(但CoreData并不是此篇文章介绍的重点)。数据库适合储存大规模数据,而且查找起来也比上述方式方便,所以大量储存的时候,还是要动用数据库,这也是我们放弃GVUserDefaults的原因。数据库的基本知识数据库首先要有数据Data,然后数据多了名字就升级了称为数据库DataBase,这个时候就需要有管理系统去管理数据库也就是DataBaseManagerSystem,最后佐以DataBaseAdministrator及上述名称成为了一个系统就是所谓的DataBaseSystem。Data --> DataBase --> DataBaseManagerSystem --> DataBaseSystemData: 数据库存储的基本对象。DataBase: 说起来数据库,大家都有一个模模糊糊的概念,不就是一个存放数据的大仓库吗,这还有什么好说的。其实这样理解就已经很好了,但是说的更专业一点就是数据库是一个以某种有组织的方式存储的数据集合。DataBaseManagerSystem: 数据库管理系统是位于用户与操作系统之间的一层数据管理软件。常见的DBMS有MySQL、PostgreSQL、 Microsoft SQL Server、Oracle、Sybase、IBM DB2。当然这些都是用于服务端的DBMS,移动端用的DBMS是SQLite3,这也是本文讲述的重点。DataBaseSystem: 在计算机系统中引入数据库后的系统,一般由数据库,数据库管理系统,应用系统,数据库管理成员(DBA)构成。一般情况下称数据库系统为数据库,所以有时候我们就会感到迷糊,你说DBS,他以为DB,你转到DB上了,他又开始讲DBS。所以真正想理解透一些知识的时候,基本概念一定要清晰一些,这样才不容易迷糊。SQL语句SQL(Structured Query Language),结构化查询语言,专门用来与数据库通信的语言。既然要操作数据库,SQL语句是必须要会写的。下面我简单列举几条简单的SQL语句仅供参考。想要学习更多的SQL语句的知识,请查阅其他资料,本篇在这儿不过多叙述。这里以学生表为例写几条简单的SQL语句//&创表(table)一张学生表&表名:student
&&&字段id:&&学生编号,作为主键,类型为整形
&&&字段name:学生名字,类型为字符串,并且不能为空值
&&&字段age:&学生年龄,类型为整形可为空。
&&&其中字段又称之为列(column)
create&table&if&not&exists&student&(
&&&&id&integer&primary&key&autoincrement,&
&&&&name&text&not&null,&
&&&&age&integer);
//&删除学生表
drop&table&if&exists&
//&插入一条记录,主键id会自增长自动赋值,
&&&其中记录又称之为行(row)
insert&into&student&(name,&age)&values&('小明',&20);
//&删除名字为小明的学生,
&&&这里的关键字where就是条件,如果无此条件,则影响整张表
delete&from&student&where&name&=&'小明';
//&更新符合条件的记录
update&student&set&age&=&21&where&name&=&'小明';
//&查询符合条件的记录
select&*&from&student&where&name&=&'小明';数据库的使用如果你没有使用CoreData,那么无论你使用的是纯C语言的SQLite3库,还是使用对其进行封装了的FMDB,你都要设计出适合自己业务的表结构。关于表的设计,可以有两种设计模式。数据库表的设计第一种设计方式以模型中的每个属性作为表的一个字段,这样在查询、读取放面操作起来更为方便,但是我个人感觉这种模式适合的业务是记录条数不多。而且字段尽可能的不要更改。创建好表之后,在去修改表结构还是听麻烦的一件事的。具体使用,可参考下面的代码:@interface&Student&:&NSObject
@property&(nonatomic,&copy)&NSString&*
@property&(nonatomic,&assign)&NSUInteger&
//&数据储存的路径
NSString&*document&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES)&lastObject];
NSString&*dbpath&=&[document&stringByAppendingPathComponent:@"toyun.sqlite"];
//&链接数据库
self.db&=&[FMDatabase&databaseWithPath:dbpath];
//&打开数据库
if&([self.db&open])&{
&&&&[self.db&executeUpdate:@"create&table&if&not&exists&student&(&id&integer&primary&key&autoincrement,&name&text&not&null,&age&integer&not&null)"];
//&实例化对象,即要储存的对象
NSMutableArray&*array&=&[NSMutableArray&array];
for&(NSInteger&i&=&0;&i&<&10;&i++)&{
&&&&Student&*student&=&[[Student&alloc]&init];
&&&&student.name&=&[NSString&stringWithFormat:@"小明%ld",&i];
&&&&student.age&=&arc4random()&%&20&+&10;
&&&&[array&addObject:student];
//&将数据库插入表中
for&(Student&*student&in&array)&{
&&&&[self.db&executeUpdateWithFormat:@"insert&into&student&(name,&age)&values&(%@,&%ld)",&student.name,&student.age];
[self.db&close];
NSLog(@"dbpath&&&===&&&%@",&dbpath);第二种设计方式这一种设计模式是将model作为一个字段直接将model转为NSData储在此字段中,在这里要指出的是model必须实现NSCoding协议,不过实际项目中我们字典转模型大都是使用第三方库,而现在比较流行的三个字典转模型的第三方库Mantle、MJExtension、YYModel都默认对此进行了处理,所以这儿稍微注意一下就好。第二种方法更适合于记录条数比较多,和业务的相关性不是太敏感,而且如果有查找排序这样的需求的话,可以从model挑出某些属性作为表中附带的一些字段。具体使用,参考下面的代码:@interface&Student&:&NSObject&@property&(nonatomic,&copy)&NSString&*
@property&(nonatomic,&assign)&NSUInteger&
@implementation&Student
-&(void)encodeWithCoder:(NSCoder&*)aCoder&{
&&&&[aCoder&encodeObject:_name&forKey:@"name"];
&&&&[aCoder&encodeInteger:_age&forKey:@"age"];
-&(nullable&instancetype)initWithCoder:(NSCoder&*)aDecoder&{
&&&&if&(self&=&[super&init])&{
&&&&&&&&_name&=&[aDecoder&decodeObjectForKey:@"name"];
&&&&&&&&_age&=&[aDecoder&decodeIntegerForKey:@"age"];
&&&&return&
NSString&*document&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES)&lastObject];
NSString&*dbpath&=&[document&stringByAppendingPathComponent:@"yeemiao.sqlite"];
self.db&=&[FMDatabase&databaseWithPath:dbpath];
if&([self.db&open])&{&&&&&&&&
&&&&[self.db&executeUpdate:@"create&table&if&not&exists&student&(id&integer&primary&key&autoincrement,&model&blob)"];
NSMutableArray&*array&=&[NSMutableArray&array];&&&&
for&(NSInteger&i&=&0;&i&<&10;&i++)&{
&&&&Student&*student&=&[[Student&alloc]&init];
&&&&student.name&=&[NSString&stringWithFormat:@"小明%ld",&i];
&&&&student.age&=&arc4random()&%&20&+&10;
&&&&[array&addObject:student];
//&转为NSData,存入数据库
for&(Student&*student&in&array)&{
&&&&NSData&*data&=&[NSKeyedArchiver&archivedDataWithRootObject:student];
&&&&[self.db&executeUpdateWithFormat:@"insert&into&student&(model)&values&(%@)",&data];
//&从数据库中查数据
FMResultSet&*set&=&[self.db&executeQuery:@"select&*&from&student"];
NSMutableArray&*resultArray&=&[NSMutableArray&array];
while&(set.next)&{
&&&&NSData&*data&=&[set&objectForColumnName:@"model"];
&&&&Student&*student&=&[NSKeyedUnarchiver&unarchiveObjectWithData:data];
&&&&[resultArray&addObject:student];
[self.db&close];数据库使用中线程安全在多线程中操作数据库,我们就要考虑线程安全问题,不然就有可能引起数据错乱的问题。解决办法有很多,可以自己去加锁,但是读写速度要求高的话就不太建议加锁了。SQLite3对于多线程是直接支持的,SQLite3库提供了三种方式:single thread、multi thread、serialized。同样 FMDB自己也提供了多线程操作数据库的类FMDatabaseQueue,这个使用起来还是比较简单的。删除缓存现在大多数的App都是有本地化储存的,但是却不是每个App都对应有删除缓存的功能,起码我们自己的App是没有做删除缓存这个功能的,缓存是为了节省流量,删除缓存是为了节省空间我认为这两个功能同等重要,但是这个需求提了几次,产品不怎么重视啊!特别是在16G的版本下,这个功能还能能提升一些用户体验的。此功能到也不难实现,搞清楚各种储存方式他们把文件存储到了那个文件夹下面,不同的数据我们储存的地方明显也是不同的,然后根据需求删除对应的数据就OK了,沙盒的具体目录如下所示://&沙盒下的文件夹目录
Documents:&iTunes会同步此文件夹,不应该删除
&&&&Caches:&缓存文件夹,删除缓存主要删除的文件夹
&&&&Preferences:&NSUserDefault写入此文件夹下,iTunes会同步,不应该删除
tmp:系统创建的临时文件夹,随时有可能被删除做清除缓存功能时,可把Library/Caches文件夹下面的文件全部删除,也可以根据业务的需要删除指定的文件夹。总结此篇文章还是比较偏重于原理,对于具体的使用则没有说太多,具体使用各种各样,但是基本原理是比较统一的。关于数据库CURD由于我们不是做服务端开发,所以也没有深究,想要研究的话,可在查阅其他资料。除了上述所说的,可能在具体使用中还要考虑数据库版本迁移,数据库同步等需求。这些由于我的水平所限,也没有提到可以参考我写此文时的一篇参考博文iOS应用架构谈 。而NSUserDefault、File使用方法都很简单也都没有介绍。CoreData太过于重量级,我在项目中也没事实际运用过,这里也没有介绍。参考
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量4556点击量2428点击量2074点击量2043点击量1885点击量1809点击量1738点击量1727点击量1654
&2018 Chukong Technologies,Inc.
京公网安备89}

我要回帖

更多关于 vue 本地存储 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信