解析的基本概念
- 解析:从事先规定好的格式中提取数据
- 解析的前提:提前约定好格式,数据提供方按照格式提供格式,数据获取方按照格式获取数据
- iOS开发常见的解析:XML解析、JSON解析
1.XML解析
- XML:Extensible Markup language(可扩展标记语言),主流数据格式之一,可以用来存储和传输数据
- XML数据格式的功能:数据交换、内容管理、配置文件
XML数据结构的语法
- 声明 如:<?xml version="1.0"?>
- 节点使用一对标签标示:开始和结束标签
- 根节点是起始节点,只有一个,节点可以嵌套
- 节点可以有值,存储在一对儿标签中
XML示例
<students>
<student>
<name>你</name>
<hobby>女</hobby>
</student>
</students>
XML解析的方式
(1)SAX解析
- SAX:Simple API for XML,基于事件驱动的解析方式,逐行解析数据。(采用协议回调机制)
- NSXMLParser是iOS自带的XML解析类,采用SAX方式解析
(2)DOM解析
- DOM:Document Object Model(文档对象模型)。DOM方式解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取它的属性和值。而且通常情况下,可以借助XPath,直接查询XML节点。
- iOS中包含一个C语言的动态链接库libxml2.dylib(xcode7以后改为libxml2.tbd),解析速度比NSXMLParser快
- GDataXMLNode采用DOM方式解析数据。它是Google提供的开源XML解析类,对libxml2.tbd进行了Objective-C的封装,能对较小或中等的xml文档进行读写操作且支持XPath语法
2.JSON解析
- JSON:(JavaScript Object Notation)是一种轻量级的数据交换格式,是基于JS的一个子集,采用完全独立于语言的文本格式,易于阅读和编写,同时也易于机器解析和生成,非常适合于服务器和客户端的交互。这些特性使JSON成为理想的数据交换语言。
- JSON数据结构的功能:数据交换、内容管理、配置文件
JSON数据结构的语法
- JSON文件有两种结构:
(1)对象:"名称/值"对的集合。不同的语言中,它被理解为对象、记录、结构、字典、哈希表,有键列表,或者关联数据。以"{"开始,以"}"结束,名称和值中间用":"隔开,多个"名称/值"对之间用","隔开。
(2)数组:值的有序列表。在大部分语言中,它被理解为数组。以"["开始,以"]"结束,中间是数据。数据以","分隔。 - JSON中的数据类型:字符型、数值、BOOL、对象、数组
JSON示例
- 示例一:["value1", "value2"]
- 示例二:{"name": "张三"}
- 示例三:
[
{
"number": 1,
"name": "张三"
"sex": "男"
},
{
"number": 2,
"name": "小红",
"sex": "女"
};
{
"number": 3,
"name": "小明",
"sex": "男"
};
]
JSON解析的方式
- 原生(自带):NSJSONSerialization是系统提供的解析类,解析效率最高
- 第三方:JSONKit、SBJSON、TouchJSON(从左往右,性能依次越差)
3.XML与JSON两种数据结构的优缺点
XML优缺点
(1)优点
- 格式统一,符合标准
- 容易与其他系统进行远程交互,数据共享比较方便
(2)缺点
- XML格式文件庞大,格式复杂,传输占用带宽
- 服务器端和客户端都需要花费大量代码来解析XML,使代码变得异常复杂和不容易维护
- 客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码
- 服务器和客户端解析XML花费资源和时间
JSON优缺点
(1)优点
- 数据格式比较简单,易于读写,格式都是压缩的,占用带宽小
- 易于解析这种语言
- 支持多种语言,包括ActionScript,C,C#,ColdFusion,Java,JavaScript,
Perl,PHP,Python,Ruby等语言服务器端语言,便于服务器端的解析 - 因为JSON格式能够直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,但是完成的任务不变,且易于维护
(2)缺点
- 没有XML格式这么推广的深入人心和使用广泛,没有XML那么通用性
- JSON格式目前在Web Service中推广还属于初级阶段
-----------------------AppDelegate.m--------------------------
#import "AppDelegate.h"
#import "Header.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
self.window.rootViewController = [RootViewController new];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
-----------------------RootViewController.m--------------------------
#import "RootViewController.h"
#import "Header.h"
@interface RootViewController ()
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
FirstViewController *firstVC = [FirstViewController new];
firstVC.tabBarItem = [UITabBarItem new];
firstVC.tabBarItem.title = @"第一页";
SecondViewController *secondVC = [SecondViewController new];
secondVC.tabBarItem = [UITabBarItem new];
secondVC.tabBarItem.title = @"第二页";
ThirdViewController * thirdVC = [ThirdViewController new];
thirdVC.tabBarItem = [UITabBarItem new];
thirdVC.tabBarItem.title = @"第三页";
ForthViewController * forthVC = [ForthViewController new];
forthVC.tabBarItem = [UITabBarItem new];
forthVC.tabBarItem.title = @"第四页";
UINavigationController *fivNav = [[UINavigationController alloc]initWithRootViewController:[FifthViewController new]];
fivNav.tabBarItem = [UITabBarItem new];
fivNav.tabBarItem.title = @"第五页";
self.viewControllers = @[firstVC, secondVC,thirdVC,forthVC,fivNav];
// tabbar点击前的颜色
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:1.000 green:0.247 blue:0.965 alpha:1.000], NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
// tabbar点击后的颜色
[[UITabBarItem appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:0.138 green:0.645 blue:1.000 alpha:1.000], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
-----------------------FirstViewController.h--------------------------
#import <UIKit/UIKit.h>
#import "Header.h"
@interface FirstViewController : UIViewController
@end
-----------------------FirstViewController.m--------------------------
#import "FirstViewController.h"
@interface FirstViewController ()<NSXMLParserDelegate>
// 数据源数组
@property (nonatomic, strong) NSMutableArray *dataArray;
// 当前标签(节点)
@property (nonatomic, strong) NSString *currentElement;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 100, self.view.frame.size.width, 40);
[btn setTitle:@"XML_SAX解析" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor colorWithRed:1.000 green:0.283 blue:0.866 alpha:1.000]];
[btn addTarget:self action:@selector(Btn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)Btn
{
// 获取文件路径
// [NSBundle mainBundle]代表的是左面那个文件夹栏
// [pathForResource:@"文件名" ofType:@"文件格式"];
NSString *path = [[NSBundle mainBundle] pathForResource:@"XML" ofType:@"txt"];
// 通过路径,创建一个data对象
NSData *data = [NSData dataWithContentsOfFile:path];
// 创建SAX解析使用的对象
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
// 遵循代理
xmlParser.delegate = self;
// 开始解析
[xmlParser parse];
}
#pragma mark -------- NSXMLParserDelegate代理方法 ---------
// 1.开始解析XML文档
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
// 准备数据(自动根据数组元素个数开辟空间,最好先给0)
self.dataArray = [NSMutableArray arrayWithCapacity:0];
}
// 2.开始解析标签
/*
parser:类
elementName:标签名
namespaceURI:节点里的命名空间
*/
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
{
// 获取到当前正在解析的标签,给标签属性赋值
_currentElement = elementName;
// 如果当前解析到的标签值为"student",那么就创建model类,并且将model添加到数据源数组中
if ([elementName isEqualToString:@"student"])
{
Student *stu = [Student new];
[self.dataArray addObject:stu];
}
}
// 3.读取标签的值:这个方法,得到节点里面存的信息数据
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// 将值存入model类对应的属性中,这个方法循环执行,我们需要取的值是最后一个【包<student></student>,是按照顺序扔进数组的,挨个进行取值,所以只取最后一个,说明全部取完】
// 根据当前已经解析出来的标签取到跟stu中属性对应的值,赋值给stu中的属性
[self.dataArray.lastObject setValue:string forKey:_currentElement];
}
// 4.结束标签解析
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// 没有标签,解析结束了
_currentElement = nil;
}
// 5.结束解析文档
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
for (Student *stu in self.dataArray)
{
NSLog(@"%@", stu);
}
}
// 6.错误报告
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(@"错误报告%@", parseError);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
-----------------------SecondViewController.h--------------------------
#import <UIKit/UIKit.h>
#import "Header.h"
@interface SecondViewController : UIViewController
@end
-----------------------SecondViewController.m--------------------------
#import "SecondViewController.h"
@interface SecondViewController ()
// 数据源数组
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 100, self.view.frame.size.width, 40);
[btn setTitle:@"XML_DOM解析" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor colorWithRed:1.000 green:0.283 blue:0.866 alpha:1.000]];
[btn addTarget:self action:@selector(Btn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)Btn
{
// 获取文件路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"XML" ofType:@"txt"];
// 以data类型进行解析,将文件读入到data中
NSData *data = [NSData dataWithContentsOfFile:path];
/*
GDataXMLNode使用方法:
1.获取GDataXMLNode.h/m文件,将它们拖到工程里
2.向工程中增加"libxml2.tbd"动态库:在工程的"Build Phases"页中,找到"Link Binary With Libraries"项,点击"+"号添加"libxml2.tbd"动态库
3.在工程的"Build Settings"页中找到"Header Search Paths"项(利用搜索框搜索),添加"/usr/include/libxml2"
4.导入"GDataXMLNode.h"文件到头文件中
5.在工程的"Build Phases"页中,在"Compile Sources"项中的GDataXMLNode.m一行中添加"-fno-objc-arc"(MRC和ARC混编)
*/
// 创建GDataXMLDocument对象,此时XML文档内的所有节点以树的形式存在于GDataXMLDocument对象中
// GDataXMLDocument XML的DOM解析使用的类
// 第一个参数 : 解析的data对象
// 第二个参数 : 一般就是0
// 第三个参数 : error信息
GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
// 创建根节点对象,获取XML文档的根节点,根节点里包含了XML文档中所有的内容
GDataXMLElement *rootElement = [xmlDocument rootElement];
// 初始化数据源数组
self.dataArray = [NSMutableArray array];
// 遍历根节点<students>的所有子节点<student>
for (GDataXMLElement *subElement in rootElement.children)
{
Student *stu = [Student new];
// 再遍历子节点<student>下的子标签<name><zi><say><weapon>,取出子标签的内容,赋值给stu
for (GDataXMLElement *contactElement in subElement.children)
{
/*
// contactElement.name 表示标签名字
// contactElement.stringValue 表示标签的值
if ([contactElement.name isEqualToString:@"name"])
{
stu.name = contactElement.stringValue;
}
else if ([contactElement.name isEqualToString:@"zi"])
{
stu.zi = contactElement.stringValue;
}
else if ([contactElement.name isEqualToString:@"say"])
{
stu.say = contactElement.stringValue;
}
else if ([contactElement.name isEqualToString:@"weapon"])
{
stu.weapon = contactElement.stringValue;
}
*/
// 使用KVC对stu赋值
[stu setValue:contactElement.stringValue forKeyPath:contactElement.name];
}
// 将赋值后的model类放入数据源数组
[self.dataArray addObject:stu];
}
// 打印结果
for (Student *stu in self.dataArray)
{
NSLog(@"%@", stu);
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
-----------------------ThirdViewController.h--------------------------
#import <UIKit/UIKit.h>
#import "Header.h"
@interface ThirdViewController : UIViewController
@end
-----------------------ThirdViewController.m--------------------------
#import "ThirdViewController.h"
@interface ThirdViewController ()
// 数据源数组
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation ThirdViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 100, self.view.frame.size.width, 40);
[btn setTitle:@"JSON-FOUNDATION" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor colorWithRed:1.000 green:0.283 blue:0.866 alpha:1.000]];
[btn addTarget:self action:@selector(Btn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
// 初始化数据源数组
self.dataArray = [NSMutableArray array];
}
-(void)Btn
{
// 获取文件路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"JSON" ofType:@"txt"];
// 创建数据对象(data类型)
NSData *data = [NSData dataWithContentsOfFile:path];
// 解析JSON数据,使用系统方法NSJSONSerialization
/*
JSONObjectWithData:放入数据对象源(NSData对象)
options:
NSJSONReadingMutableContainers:表示解析完成后返回值类型为NSMutableArray 或 NSMutableDictionary
NSJSONReadingMutableLeaves:表示解析完成后返回值类型为NSMutableString
NSJSONReadingAllowFragments:返回一个任意类型的对象
error:错误信息
*/
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
// 遍历数组,放入字典
for (NSDictionary *dic in array)
{
// 初始化model类
Student *stu = [Student new];
// 使用KVC赋值
[stu setValuesForKeysWithDictionary:dic];
// 将赋值后的model类放入数据源数组
[self.dataArray addObject:stu];
}
for (Student *stu in self.dataArray)
{
NSLog(@"%@", stu);
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
-----------------------ForthViewController.h--------------------------
#import <UIKit/UIKit.h>
#import "Header.h"
@interface ForthViewController : UIViewController
@end
-----------------------ForthViewController.m--------------------------
#import "ForthViewController.h"
@interface ForthViewController ()
// 数据源数组
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation ForthViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 100, self.view.frame.size.width, 40);
[btn setTitle:@"JSON-KIT" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor colorWithRed:1.000 green:0.283 blue:0.866 alpha:1.000]];
[btn addTarget:self action:@selector(Btn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)Btn
{
// 获取路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"JSON" ofType:@"txt"];
// 创建data对象
NSData *data = [NSData dataWithContentsOfFile:path];
// 解析JSON数据,使用JSONKit(第三方)中的方法
// 在工程的"Build Phases"页中,在"Compile Sources"项中的GDataXMLNode.m一行中添加"-fno-objc-arc"(MRC和ARC混编)
NSArray *array = [data objectFromJSONData];
// 输出化数据源数组
self.dataArray = [NSMutableArray array];
for (NSDictionary *dic in array)
{
// 初始化model类
Student *stu = [Student new];
// KVC赋值
[stu setValuesForKeysWithDictionary:dic];
// 给数据源数组赋值
[self.dataArray addObject:stu];
}
for (Student *stu in self.dataArray)
{
NSLog(@"%@", stu);
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
-----------------------FifthViewController.h--------------------------
#import <UIKit/UIKit.h>
#import "Header.h"
@interface FifthViewController : UITableViewController
@end
-----------------------FifthViewController.m--------------------------
#import "FifthViewController.h"
@interface FifthViewController ()
// 数据源数组
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation FifthViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[FifthTableViewCell class] forCellReuseIdentifier:@"cell"];
self.tableView.tableFooterView = [UIView new];
self.tableView.bounces = NO;
self.dataArray = [NSMutableArray array];
[self Parse];
}
- (void)Parse
{
// 获取文件路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"movie" ofType:@"txt"];
// 创建data对象
NSData *data = [NSData dataWithContentsOfFile:path];
// 解析
self.dataArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.dataArray.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *title = [self.dataArray[section] valueForKey:@"title"];
return title;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *array = [self.dataArray[section] objectForKey:@"data"];
return array.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FifthTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// 赋值
cell.movie = [Movie movieWithDictionary:self.dataArray[indexPath.section][@"data"][indexPath.row]];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
-----------------------FifthTableViewCell.h--------------------------
#import <UIKit/UIKit.h>
#import "Header.h"
@interface FifthTableViewCell : UITableViewCell
@property (nonatomic, strong) UIImageView *movieImg;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) Movie *movie;
@end
-----------------------FifthTableViewCell.m--------------------------
#import "FifthTableViewCell.h"
@implementation FifthTableViewCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
self.movieImg = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
[self.contentView addSubview:self.movieImg];
self.titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(70, 10, 200, 20)];
self.titleLabel.font = [UIFont systemFontOfSize:12];
[self.contentView addSubview:self.titleLabel];
}
return self;
}
-(void)setMovie:(Movie *)movie
{
_movieImg.image = [UIImage imageNamed:movie.icon];
_titleLabel.text = movie.title;
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
-----------------------Student.h--------------------------
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *zi;
@property (nonatomic, strong) NSString *say;
@property (nonatomic, strong) NSString *weapon;
@end
-----------------------Student.m--------------------------
#import "Student.h"
@implementation Student
// 防崩
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
}
- (NSString *)description
{
return [NSString stringWithFormat:@"%@; %@; %@; %@",_name, _zi, _say, _weapon];
}
@end
-----------------------Movie.h--------------------------
#import <Foundation/Foundation.h>
@interface Movie : NSObject
@property (nonatomic, strong) NSString *ID;
@property (nonatomic, strong) NSString *img;
@property (nonatomic, strong) NSString *icon;
@property (nonatomic, strong) NSString *title;
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;
+ (instancetype)movieWithDictionary:(NSDictionary *)dictionary;
@end
-----------------------Movie.m--------------------------
#import "Movie.h"
@implementation Movie
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
}
- (instancetype)initWithDictionary:(NSDictionary *)dictionary
{
if (self = [super init])
{
[self setValuesForKeysWithDictionary:dictionary];
}
return self;
}
+ (instancetype)movieWithDictionary:(NSDictionary *)dictionary
{
return [[Movie alloc] initWithDictionary:dictionary];
}
@end
-----------------------XML.txt--------------------------
<students>
<student>
<name>刘备</name>
<zi>玄德</zi>
<say>汉贼不两立,王业不偏安</say>
<weapon>雌雄一对剑</weapon>
</student>
<student>
<name>关羽</name>
<zi>云长</zi>
<say>吾弟张翼德于百万军中取上将首级,如探囊取物</say>
<weapon>青龙偃月刀</weapon>
</student>
<student>
<name>张飞</name>
<zi>翼德</zi>
<say>吾乃燕人张翼德是也</say>
<weapon>丈八蛇矛</weapon>
</student>
<student>
<name>赵云</name>
<zi>子龙</zi>
<say>吾乃常山赵子龙</say>
<weapon>龙胆</weapon>
</student>
<student>
<name>黄忠</name>
<zi>汉升</zi>
<say>交给老臣 要瞄准了</say>
<weapon>卷云刀、画雀弓</weapon>
</student>
<student>
<name>马超</name>
<zi>孟起</zi>
<say>马孟起,参见!</say>
<weapon>龙骑尖枪</weapon>
</student>
</students>
-----------------------JSON.txt--------------------------
[
{
"name":"刘备",
"zi":"玄德",
"say":"汉贼不两立,王业不偏安",
"weapon":"雌雄一对剑"
},
{
"name":"关羽",
"zi":"云长",
"say":"吾弟张翼德于百万军中取上将首级,如探囊取物尔",
"weapon":"青龙偃月刀"
},
{
"name":"张飞",
"zi":"翼德",
"say":"吾乃燕人张翼德是也",
"weapon":"丈八蛇矛"
},
{
"name":"赵云",
"zi":"子龙",
"say":"吾乃常山赵子龙",
"weapon":"龙胆"
},
{
"name":"黄忠",
"zi":"汉升",
"say":"交给老臣 要瞄准了",
"weapon":"卷云刀、画雀弓"
},
{
"name":"马超",
"zi":"孟起",
"say":"马孟起,参见!",
"weapon":"龙骑尖枪"
}
]
-----------------------movie.txt--------------------------
[
{
"data":
[
{
"id": "185163",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2233706697.jpg",
"icon": "1-1.jpg",
"title": "速度与激情7"
},
{
"id": "178554",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2237747953.jpg",
"icon": "1-2.jpg",
"title": "复仇者联盟2:奥创纪元"
},
{
"id": "184885",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2257944916.jpg",
"icon": "1-3.jpg",
"title": "捉妖记"
},
{
"id": "179232",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2253038483.jpg",
"icon": "1-4.jpg",
"title": "煎饼侠"
},
{
"id": "184884",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2257475080.jpg",
"icon": "1-5.jpg",
"title": "王朝的女人·杨贵妃"
},
{
"id": "185107",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2246885606.jpg",
"icon": "1-6.jpg",
"title": "杀破狼2"
},
{
"id": "184895",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2239530046.jpg",
"icon": "1-7.jpg",
"title": "念念"
},
{
"id": "185212",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2257443441.jpg",
"icon": "1-8.jpg",
"title": "谜城"
},
{
"id": "166715",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2251450614.jpg",
"icon": "1-9.jpg",
"title": "道士下山"
},
{
"id": "184407",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2244110255.jpg",
"icon": "1-10.jpg",
"title": "横冲直撞好莱坞"
},
{
"id": "185400",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2259282065.jpg",
"icon": "1-11.jpg",
"title": "破风"
},
{
"id": "185346",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2250399288.jpg",
"icon": "1-12.jpg",
"title": "小时代4:灵魂尽头"
},
{
"id": "184239",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2238949728.jpg",
"icon": "1-13.jpg",
"title": "左耳"
},
{
"id": "107286",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2253155703.jpg",
"icon": "1-14.jpg",
"title": "栀子花开"
},
{
"id": "184195",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2232079769.jpg",
"icon": "1-15.jpg",
"title": "咱们结婚吧"
}
],
"title": "热门电影"
},
{
"data":
[
{
"id": "184906",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2266591722.jpg",
"icon": "2-1.jpg",
"title": "挑战者联盟"
},
{
"id": "184508",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2257436776.jpg",
"icon": "2-2.jpg",
"title": "偶像来了"
},
{
"id": "184244",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2249066690.jpg",
"icon": "2-3.jpg",
"title": "爸爸去哪儿第三季"
},
{
"id": "185018",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2250415721.jpg",
"icon": "2-4.jpg",
"title": "中国好声音 第4季"
},
{
"id": "185025",
"img": "http://img3.douban.com/view/movie_poster_cover/lpst/public/p2257441314.jpg",
"icon": "2-5.jpg",
"title": "蒙面歌王"
},
{
"id": "183980",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2244976758.jpg",
"icon": "2-6.jpg",
"title": "极限挑战"
},
{
"id": "43161",
"img": "http://img4.douban.com/view/photo/thumb/public/p2249051446.jpg",
"icon": "2-7.jpg",
"title": "真心英雄"
},
{
"id": "175640",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2261003217.jpg",
"icon": "2-8.jpg",
"title": "变形计"
},
{
"id": "180129",
"img": "http://img4.douban.com/view/movie_poster_cover/lpst/public/p2231248476.jpg",
"icon": "2-9.jpg",
"title": "金星脱口秀"
}
],
"title": "热门综艺"
}
]