- 解析: 从事先规定好的格式中提取数据
- XML : 主流数据格式之一, 可以用来存储和传输数据
- JSON: 采用完全独立于语言的文本格式, 被称为理性的数据交换语言
-
XML → SAX 与 DOM 按钮
#pragma mark - SAX按钮
- (IBAction)saxMethod:(id)sender
{
// 1. 获取数据文件的位置
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"StudentXML" ofType:@"txt"];
// 2. 根据路径, 读取出来数据
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSLog(@"%@",data);
}
#pragma mark - DOM按钮
- (IBAction)domMethod:(id)sender
{
// 1. 获取数据文件的位置
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"StudentXML" ofType:@"txt"];
// 2. 根据路径, 读取出来数据
NSData *data = [NSData dataWithContentsOfFile:filePath];
// 3. 创建解析对象
GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
// 4. 获取根
GDataXMLElement *rootElement = document.rootElement;
// 5. 获取根节点下的所有子节点
NSArray *studentArrayElement = rootElement.children;
// 6. 遍历每一个student
self.allStudentMutableArray = [[NSMutableArray alloc] init];
for (GDataXMLElement *stuElement in studentArrayElement) {
// 7. 每遍历一次就创建一个模型对象
Student *stu = [Student new];
// 8. 遍历该student下所有子节点
for (GDataXMLElement *stuSubElement in stuElement.children) {
// 9. 将每次获取到值赋值给stu模型对象, 使用KVC方式
[stu setValue:stuSubElement.stringValue forKey:stuSubElement.name];
}
// 10. 将设置好模型对象添加到数组
[_allStudentMutableArray addObject:stu];
[stu release];
}
}
JSON解析工具 → Seriallizationer Kit
- (IBAction)jsonSeriallization:(id)sender
{
// 1. 获取路径
NSString *path = [[NSBundle mainBundle]pathForResource:@"StudnetJSON.txt" ofType:nil];
// 2. 获取数据
NSData *data = [NSData dataWithContentsOfFile:path];
// 3.解析并得到结果
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(@"%@", array);
}
- (IBAction)jsonKit:(id)sender
{
// 1. 获取路径
NSString *path = [[NSBundle mainBundle]pathForResource:@"StudnetJSON.txt" ofType:nil];
// 2. 获取数据
NSData *data = [NSData dataWithContentsOfFile:path];
// 3. 使用JSONKit将data类型转为数组
NSArray *array = [data objectFromJSONData];
NSLog(@"%@", array);
// 将数组转为json串
NSString *jsonStr = [array JSONString];
NSLog(@"%@", jsonStr);
// 将字典转为json串
NSDictionary *dict = @{
@"小米":@"xiaohong",
@"yaoyao":@"hehe",
@"hehe":@"xiaomi"
};
NSString *dictJsonStr = [dict JSONString];
NSLog(@"%@", dictJsonStr);
}
- http://(超文本传输协议)
- c/s是客户端和服务器,b/s是浏览器和服务器。
- c/s在客户端要安装软件的,b/s只要有IE就可以浏览。
- c/s的扩展升级比较困难,b/s就很容易的。
- c/s的安全性好一些,b/s就没有c/s的高。
- c/s一般用在局域网,b/s一般用在广域网。
- ------------------------------------------------
- C/S运用在有专用性的场合。比如说一个公司的财务管理。财务处使用专用的财务管理软件将日常的财务情况提交到财务服务器。方便统计。。。之类。
- B/S就等于建了一个公司的网站。公司内部网和互联网都可以浏览到。只是权限不同。现在许多校园网都这样。
- 请求方式GET POST都是给服务器传输数据两种请求方式 同步异步是连接方式
- 不同点:
- 1.给服务器传输数据的方式:
- GET: 通过网址字符串
- POST: 通过data;
- 2. 传输数据的大小
- GET: 网址字符串最多255字节
- POST: 使用NSData 容量超过1G
- 3. 安全性:
- GET: 所有传输给服务器的数据, 显示在网址里, 类似于密码的明文输入, 直接可见
- POST: 数据被转成NSData(二进制数据). 类似于密码的密文输入, 无法直接读取
- 同步连接: 程序容易出现卡死现象
- 异步连接: 等待数据返回
- 异步连接有两种实现方式: 设置代理 接受数据... 实现block
-
POST 异步
// 1. 准备网址
NSURL *url = [NSURL URLWithString:@"http://172.16.12.92/Class36Students"];
// 2. 创建请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 3. 使用创建链接对象 发送请求(使用Block方式)
__block RootTableViewController *weakSelf = self;
[NSURLConnection sendAsynchronousRequest:request
queue:[[NSOperationQueue new] autorelease]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 4.0 解析数据到大字典中
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
// 4.1 将大字典的数据转为模型并储存
// 给大数组初始化 遍历每个学生的数组 并添加到大数组
weakSelf.allDataMutableArray = [NSMutableArray array];
for (NSDictionary *studentDict in dict[@"students"]) {
Student *stu = [Student new];
[stu setValuesForKeysWithDictionary:studentDict];
[_allDataMutableArray addObject:stu];
[stu release];
}
// 5. 回到主线程 刷新页面
dispatch_sync(dispatch_get_main_queue(), ^{
// reloadData是刷新所有数据
[weakSelf.tableView reloadData];
});
}];
}
- 网络请求步骤: 1丶NSURL 2丶NSURLRequest 3丶NSURLConnection 4丶处理Error或者返回数据
- 网络接口返回的JSON或XML数据中.通常不会直接包含图片, 而是给出图片的URL
- 图片下载流程与普通网路相同
- 1. 创建一个request
- 2. 建立urlConnection
- 3. 使用请求到的数据
- 为了便于后续使用, 可以将图片下载封装到一个类里面(ImageDownloader)
- ImageDownloader 允许外界指定URL 提供 开始下载和取消下载功能 并提供delegate或block将图片传递到外界
- Model类注意事项
- 1. 除了包含必要数据外 还要包含一个ImageDownloader对象
- 2. 包含一个image
- 3. 包含一个图片是否正在下载的bool 值(用于判断是否需要开始下载)
- KVO: 键值观察者 是观察者设计模式的一种具体实现
- KVO触发机制: 一个对象(观察者) 检测另一个对象(被观察者)的某属性是否发生变化,若被检测的属性发生更改会触发观察者一个方法
- KVO使用步骤:
- 1. 注册观察者
- 2. 实现回调方法
- 3. 触发回调方法
- 4. 移除观察者
- KVO注意事项: 观察者销毁之前, 移除观察者, 否则会出现程序异常
- ImageDownloader封装了下载过程 提供了下载相关的方法
- tableView可以借助KVO监测下载, 及时更新cell
-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 使用storyBoard 不需要创建cell 如果重用队列不存在cell StoryBoard会默认帮我们创建
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"news" forIndexPath:indexPath];
// 取出将要显示的模型对象
News *news = _allDataMutableArray[indexPath.row];
// 显示模型中数据
cell.textLabel.text = news.movieName;
cell.detailTextLabel.text = news.movieId;
// 赋值图片
if (news.imageData != nil) {
cell.imageView.image = news.imageData;
}else{
// 图片数据为空
// 监听图片数据是否请求下来 (KVO)
// news 被监听者
// observer:self 监听者
// keyPath:@"imageData" 监听的属性
// options 监听的是旧值还是新值
// context 上下文对象 (传递的参数)
[news addObserver:self
forKeyPath:@"imageData"
options:NSKeyValueObservingOptionNew
context:indexPath];
}
return cell;
}
#pragma mark - KVO 监听后被执行的方法 意味着监听对象的属性发送了变化
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
// 如果要监听多个对象的属性的时候, 必须要添加判断
if ([keyPath isEqualToString:@"imageData"]) {
// 1. 获取新的图片数据
UIImage *newImageData = change[NSKeyValueChangeNewKey];
// 2. 获取cell
NSIndexPath *indexPath = (NSIndexPath *)context;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = newImageData;
// 3. 刷新当前行
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
// 4.取消键值对监听
[object removeObserver:self forKeyPath:keyPath];
}
}
创建时自动调用setter方法 提前加载好图片
#pragma mark - 重写pic_url setter方法
- (void)setPic_url:(NSString *)pic_url
{
if (_pic_url != pic_url){
[_pic_url release];
_pic_url = [pic_url copy];
// 发起网络请求
__block News *weakSelf = self;
// 图片数据为空 请求数据
[ImageDownload imageDownloadWithUrlStr:self.pic_url result:^(UIImage *img)
{
// 将获取到数据赋值
weakSelf.imageData = img;
}];
}
}
- 数据持久化 → 数据的永久存储
- 为什么要做数据持久化→ 存储在内存中数据,程序关闭,内存释放,数据丢失.这种数据是临时的
- 数据持久化的本质: 数据保存成文件 存储到程序的沙盒中
- 沙盒构成
- { Document 存储用户数据, 需要备份的信息
- Library/Caches 存储缓存文件, 程序专用支持文件
- Library/Preferences 存储应用程序的偏好设置文件
- .app 程序包(IOS8 app不存储在沙盒中, 有单独文件夹存储所有程序app包)
- tmp 存储临时文件 例如: 下载zip 解压后删除
- }
-
// 1. 获取沙盒根目录
NSString *rootPath = NSHomeDirectory();
NSLog(@"rootPath: %@", rootPath);
// 2. 获取NSBundle文件路径
NSBundle *mainbundle = [NSBundle mainBundle];
NSLog(@"Bundle: %@", mainbundle);
// 2.1 获取Bundle里的数据
//NSString * filePath = [mainbundle pathForResource:@"name.type" ofType:nil];
// 3. 直接Document文件夹的路径
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
// 作为参数
// NSDocumentDirectory
// NSCachesDirectory
// NSLibraryDirectory
// 直接获取根目录 NSHomeDirectory()
// 直接获取tmp目录 NSTemporaryDirectory()
// 将数组写入文件
NSString *arrayPath = [documentsPath stringByAppendingString:@"array.xml"];
NSArray *array = @[@"阿大", @"小二",@"小三",@"杀猪的"];
[array writeToFile:arrayPath atomically:YES];
// 读取
NSArray *array2 = [NSArray arrayWithContentsOfFile:arrayPath];
NSLog(@"%@", array2);
// 将字典写入文件
NSString *dictPath = [documentsPath stringByAppendingString:@"/dict.plist"];
NSDictionary *dict = @{
@"key1": array2,
@"key2": array2
};
// 写入
[dict writeToFile:dictPath atomically:YES];
// 读取
NSDictionary *dict2 = [NSDictionary dictionaryWithContentsOfFile:dictPath];
NSLog(@"%@", dict2)
- 通过代码查找到程序沙盒相对路径 (字典 数组 图片)
- 简单对象写入文件只能是NSString NSArray NSDictionary NSData
- 复杂对象:
- 1. 在Foundation框架内不存在的数据类
- 2. 无法在程序内通过writeToFile类型的写法写入到文件内
- 3. 复杂对象至少包含一个实例对象
- 复杂对象无法通过writeToFile方法进行数据持久化,只能通过将复杂对象转换为NSData,通过writeToFile:进行数据持久化
- 将复杂对象转换为NSData 通过归档,,,,,将NSData转换为复杂对象通过反归档
- 复杂对象要接受NSCoding协议
- @interface Person : NSObject<NSCoding>
- //对person对象进行归档 此方法执行 //对person中想要进行归档的所有属性 进行编码操作
- - (void)encodeWithCoder:(NSCoder *)aCoder
- {
- [aCoder encodeObject:self.name forKey:@"name"];
- [aCoder encodeObject:self.gender forKey:@"gender"];
- [aCoder encodeInteger:self.age forKey:@"age"];
- }
- 复杂对象 写入文件
- //对复杂对象person 进行归档 person => NSData Person * p = [[Person alloc] init]; p.name = @"某个女生";
- p.gender = @"女";
- p.age = 26;
- NSMutableData * data = [NSMutableData dataWithCapacity:40];
- //创建归档工具对象
- NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
- //归档
- [archiver encodeObject:p forKey:@"person"];
- //结束归档
- [archiver finishEncoding];
- //将归档后NSData 写入文件 存储在沙盒中
- NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
- NSUserDomainMask, YES) lastObject];
- NSString * filePath = [documentPath stringByAppendingPathComponent:@"SavePerson"];
- [data writeToFile:filePath atomically:YES];
- //根据文件路径 读取data
- NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
- NSUserDomainMask, YES) lastObject];
- NSString * filePath = [documentPath stringByAppendingPathComponent:@"SavePerson"];
- NSData * data = [NSData dataWithContentsOfFile:filePath];
- //将NSData 通过反归档转化成person 对象
- NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
- //通过反归档得到复杂对象
- Person * p = [unarchiver decodeObjectForKey:@"person"];
- [unarchiver finishDecoding];
- NSLog(@"name = %@",p.name);
- NSLog(@"gender = %@",p.gender);
- NSLog(@"age = %ld",p.age);
- 什么是数据库
- 1. 以一定方式存储在一起
- 2. 能为多个用户共享
- 3. 具有尽可能小的冗余度
- 4. 与程序彼此独立的数据集合
- SQL语句
- 数据插入(Insert) 更新命令(Update) 删除(Delete) 检索(Select)
- SQLite嵌入式数据库
- Linux 系统级的SQLite技术实现框架
- 1. 引入 <sqlite3.h> 头文件
- 2. 打开数据库
- 3. 执行SQL命令
- 4. 关闭数据库
- SQLite重用系列函数
- 1. sqlite3_exec()
- 2. sqlite3_prepare_v2(),sqlite3_step(),sqlite3_finalize()
- 3. sqlite3_bind()
- 4. sqlite3_column()
- UICollectionView 称之为集合视图
- 在UICollectionView中 cell布局比tableView复杂需要使用一个类描述集合视图布局和行--UICollectionViewLayout(基类)
- 创建集合视图步骤
- 1⃣️ 使用系统布局UICollectionViewFlowLayout
- 2⃣️ 设置代理 设置数据源 (给CollectionView指定数据源它 负责提供数据与显示)
- 3⃣️ 设置自定义Cell
// 初始化集合视图
// 1. 创建布局对象
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout new] autorelease];
// 设置每个大小
flowLayout.itemSize = CGSizeMake(100, 100);
flowLayout.minimumInteritemSpacing = 7; // 行间距
flowLayout.minimumLineSpacing = 7; // 列间距
// 滚动方向
flowLayout.scrollDirection = UICollectionViewScrollPositionCenteredVertically;
// 设置头区大小 (当滑动为横向滑动时候, 主要头区和尾区的宽度大小)
flowLayout.headerReferenceSize = CGSizeMake(self.bounds.size.width, 20);
// 设置尾区大小
flowLayout.footerReferenceSize = CGSizeMake(self.bounds.size.width, 20);
// 设置边缘嵌入的值
flowLayout.sectionInset = UIEdgeInsetsMake(0, 5, 0, 5);
// 2. 创建集合视图, 使用布局
self.collectionView = [[[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:flowLayout] autorelease];
[self addSubview:_collectionView];
// 头部重用机制
[self.rootView.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:@"UICollectionElementKindSectionHeader"withReuseIdentifier:@"header"];
// 尾区重用机制
[self.rootView.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:@"UICollectionElementKindSectionFooter"withReuseIdentifier:@"footer"];
#pragma mark 处理每个分区的头和尾区
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
// 对于集合视图 (UICollectionView )来说 头区 尾区使用的是UICollectionReusableView 类
// 而不是UIView 设置的时候 也需要使用重用机制
// 使用kind去判断当前显示尾区还是头区
if ([kind isEqualToString:UICollectionElementKindSectionHeader]){
// 头区
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"header" forIndexPath:indexPath];
headerView.backgroundColor = [UIColor whiteColor];
return headerView;
}else{
// 尾区
UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"footer" forIndexPath:indexPath];
footerView.backgroundColor = [UIColor redColor];
return footerView;
}
}
- 单例对象使用 单例对象生命周期从创建一直到结束,
※豆瓣