学习了iOS开发,就能够编写运行在iPhone上/ipad的应用程序
IOS开发的准备:
1.OC语言
2.Xcode
3.Mac OS X
调试设备(可选):真机测试
开发者证书(可选):在APPstore申请
第一个IOS程序运行过程:
1.每个应用程序都有属于本身的UIWindow,UIWindow继承自UIView
2.UIView面临的问题
1>谁来控制器UIView之间的切换?
2>谁来管理UIView的生命周期?
3>谁来给UIView装配数据?
4>谁来监听UIView的事件?
答案都是:控制器(UIViewController)
ios的设计采起了MVC模式
IOS的运行过程原理:
1.首先执行main函数
2.执行UIApplicationMain函数
3.UIApplicationMain函数内部
1>建立一个UIApplication实例.这个
UIApplication对象是单粒的,一个IOS程序对应一个UIApplication对象
2>UIApplication对象是应用程序的象征
3>开启一个消息循环(main loop),用来监听用户的操做
4>再建立一个UIApplication的delegate对象,负责监听UIApplication的生命周期
5>当UIApplication的生命周期发送改变时,会给代理delegate发送不一样消息
*当第一次运行程序时候:
didFinishLaunchingWithOptions(加载完毕)->
applicationDidBecomeActive(获取焦点)
*当点击home键时候:
applicationWillResignActive(失去焦点)->
applicationDidEnterBackground(进入后台)
*当再次点击应用图标从新进入应用时候:
applicationWillEnterForeground(进入前台)->
applicationDidBecomeActive(获取焦点)html
UIApplication函数的参数:
*第四个参数用来指定UIApplication的代理
*第三个参数用来指定UIApplication的代理的类名或者子类,若是为nil,就默认为nilios
1iOS开发概述:
开发iOS程序的步骤:
(1)搭建界面;
(2)监听事件;(连线)
(3)编写代码
0519
iOS系统架构:基于UNIX。分为4个层次:
核心操做系统层(最底层)Core OS
核心服务层 Core Services
媒体层 Media
可触摸层 Cocoa Touchgit
company identifier 公司标示符,反向域名
正向域名:www.baidu.com 用来表示一台网络主机
反向域名:cn.itCast. 用来标示产品的
bundle identifier产品惟一标示符
bundle ID=公司反向域名+产品
注意点:在模拟器上只能有一个惟一的标示符;
在APPStore上全部应用程序Bundle ID是惟一的(不支持中文,若是是上架产品,须要修改)程序员
UIView:屏幕上能看得见摸的着的东西,翻译叫作视图\控件\组件
每个UIView都是一个容器,能容纳其余UIView。
父控件和子控件:
UIButton,UILabel,UITextField都继承UIView。
UIViewController是UIView的大管家,经过程序代码处理。工做:
(1)UIView的建立,显示和销毁;
(2)UIView跟用户的交互;
(3)监听UIView内部的事件;
UIViewController 是负责程序的控制;UIView是负责界面的显示的。
IBAction和IBOutlet:
IBAction原名是Interface Builder,用来操做创建关系,本质就是一个void,
只有返回值声明为IBAction方法,才能跟storyboard控件进行连线。
IBOutlet用来和界面上元素创建关系,用来得到修改界面控件属性.
退出键盘的方式:
1resignFirstResponder
2endEditingweb
如何修改控件状态:
每个UI控件都是一个对象;每个UI控件都有本身的位置和尺寸,有本身的父控件和子控件;
修改UI控件的状态,其实就是修改控件对象的属性;
全部的UI控件最终都继承自UIView,UI控件的
公共属性都定义在UIView中。
UIKit坐标系:坐标系原点在左上角,x值向右正向延伸,Y值向下正向延伸。
UIView的常见属性:
@property(nonatomic,readonly)UIView *superview;
得到本身的父控件对象
@property(nonatomic,readonly,copy)NSArray *subviews;
得到本身的全部子控件对象
@property(nonatomic)NSInteger tag;
控件的ID(标识),父控件能够经过tag找到对应的子控件
@property(nonatomic)CGAffineTransform transform;
控件的形变属性(旋转,缩放,平移等属性)
UIView的常见方法:
-(void)addSubview:(UIView *)view;
-(void)removeFromSubview;
-(UIView *)viewWithTag:(NSInteger)tag;面试
去除autolayout:若是发现经过代码没法修改控件的位置或者尺寸时。算法
UIButton的状态:normal;highlighted;disabled。
经过修改控件的frame属性就能够修改控件在屏幕的位置尺寸。
实现简单动画:
头尾式:[UIView beginAnimations:nil context:nil];
[UIView commitAnimations];
Block式:[UIView animateWithDuration:0.5 animations:^{数据库
}];
修改控件的位置:(frame)
frame.origin(CGRect)
center (CGPoint)
修改控件的尺寸:(size)
frame.size
bounds.size
transforms属性:能够修改控件位移(位置尺寸),缩放,旋转
4>.h & .m
.h 是程序接口,对外提供方法声明
.m 是程序的实现,负责方法的具体实现
注意:在OC中,不容许直接修改对象的结构体属性的成员;
容许修改对象的结构体属性。
UIView常见属性:
@property(nonatomic)CGRect frame;父控件原点,定义控件位置和大小
@property(nonatomic)CGRect bounds;本身左上角为原点,定义控件的大小(神奇)
@property(nonatomic)CGPoint center;父控件原点,定义控件的位置编程
有时候连线连不了,须要将Xcode退一下就能够了。
要想提示高亮状态的颜色必须把type的system改成custom;normal改成highlighted。
1定义属性
2建立属性对应的控件,添加到视图
3监听按钮的点击事件swift
懒加载:在须要’的时候在实例化加载在内存中
@property1setter和getter 2带下划线的成员变量
怎么懒加载?重写一个getter方法
0522
-(void)dealloc
{
//对象被销毁,系统会自动调用
}
1. @property的参数说明
========================================
ARC是苹果为了简化程序员对内存的管理,推出的一套内存管理机制
使用ARC机制,对象的申请和释放工做会在运行时,由编译器自动在代码中添加retain和release
1> strong:强指针引用的对象,在生命周期内不会被系统释放
在OC中,对象默认都是强指针
2> weak:弱指针引用的对象,系统会当即释放
弱指针能够指向其余已经被强指针引用的对象
ARC中的@property参数使用小结:
1> 控件用weak 至关于MRC的assign
2> 属性对象用strong(如:NSArray *DataList)至关于MRC的retain
3> 非对象类型用assign 至关于MRC的assign
4> 字符串NSString用copy 至关于MRC的copy
提示:在纯手码实现界面布局时,若是经过懒加载处理界面控件,须要使用strong强指针
2. 运行循环
========================================
在iOS的应用程序中,应用程序启动以后,系统即会建立一个运行循环监听用户的交互。
runloop的演示:
建立新的项目;osx,application,commandLineTool.(Foundation框架)
程序运行启动——>等待用户输入——><——处理用户输入
如下代码其本质是在运行循环中注册一个监听事件
[button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
当运行循环检测到button的UIControlEventTouchUpInside事件时,会给视图控制器(self)发送一个click消息。
1. 开发前的思路
========================================
1> 从mainBundle中加载Plist
2> 按照plist中的数据数量先肯定各个appView的大小和位置
3> 使用代码建立appView中的子控件,并显示内容
3. 关于UIButton的一些补充
========================================
3.1 按钮的类型
在iOS的控件中,只有UIButton提供了类方法,能够在实例化按钮时指定按钮的不一样类型。
UIButtonTypeCustom和[[UIButton alloc] init]是等价的
3.2 修改按钮字体
在UIButton中定义有两个readonly的属性:
1> titleLabel
2> imageView
@property中readonly表示不容许修改这两个属性的指针地址,可是能够修改其属性
注意:因为按钮的字体大小是全部状态共用的,所以能够经过
button.titleLabel.font= [UIFont systemFontOfSize:14.0];
修改按钮标签文本的字体大小
可是不能使用如下代码设置按钮标签的文本内容
button.titleLabel.text = @"下载";
由于按钮标签的文本内容是跟按钮的状态向关的
4. 动画
========================================
4.1 首尾式动画
若是只是修改控件的属性,使用首尾式动画仍是比较方便的,可是若是须要在动画完成后作后续处理,就不是那么方便了
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
// 修改属性的动画代码
// ......
[UIView commitAnimations];
4.2 块动画
块动画相对来讲比较灵活,尤其重要的是可以将动画相关的代码编写在一块儿,便于代码的阅读和理解
[UIView animateWithDuration:2.0 animations:^{
// 修改控件属性动画
label.alpha = 0.0;
} completion:^(BOOL finished) {
// 删除控件
[label removeFromSuperview];
}];
5. ***************************
*******************************
在点击supportingFiles新建plist文件(iOS-resource-propertyList)创建好array,dictionary,string
在viewController.m文件中:
1 在懒加载中经过mainBundle加载plist文件;得到全路径
2 根据全路径加载数据;
3 字典转模型;
4 赋值数据
5 返回数据
#pragma mark -懒加载
-(NSArray *)heros
{
if(_heros == nil){
//得到全路径
NSString *fullPath = [[NSBundle mainBundle]pathForResource:@“heros
” ofType:@“plist”;
//根据全路径加载数据
NSArray *dictArray = [NSArray arrayWithContentsOfFile:fullPath];
//字典转模型
NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictArray.count];
for(NSDictionary *dict in dictArray){
NJHero *hero = [NJHero heroWithDict:dict];
[models addObject:hero];
}
//赋值数据
_heros = [models copy];
}
//返回数据
return _heros;
}
在viewController.M文件中再建议一个类,继承NSOject。
在类.h中,写入以下方法
模型应该提供一个能够传入字典参数的构造方法(字典转模型的过程最好封装在模型内部)
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)xxxWithDict:(NSDictionary *)dict;
在类.m中实现方法:
- (instancetype)initWithDict:(NSDictionary *)dict{
if(self = [super init]){
[self setValueForKeysWithDictionary:dict];
}
return self;
}
+ (instancetype)xxxWithDict:(NSDictionary *)dict{
return [[self alloc]initWithDict:dict];
}
***************************
*******************************
5.2 instancetype & id
1> instancetype在类型表示上,跟id同样,能够表示任何对象类型
2> instancetype只能用在返回值类型上,不能像id同样用在参数类型上
3> instancetype比id多一个好处:编译器会检测instancetype的真实类型
5.3 在模型中添加readonly属性
// 定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
// 而若是是readonly属性,则只会生成getter方法,同时没有成员变量
@property (nonatomic, strong, readonly) UIImage *image;
@interface LFAppInfo()
{
UIImage *_imageABC;
}
- (UIImage *)image
{
if (!_imageABC) {
_imageABC = [UIImage imageNamed:self.icon];
}
return _imageABC;
}
在模型中合理地使用只读属性,能够进一步下降代码的耦合度。
5.4 使用数据模型的好处:
*** 调用方不用关心模型内部的任何处理细节!
5.1 字典转模型的好处:
1> 下降代码的耦合度
2> 全部字典转模型部分的代码统一集中在一到处理,下降代码出错的概率
3> 在程序中直接使用模型的属性操做,提升编码效率
6. XIB
========================================
Xib文件能够用来描述某一块局部的UI界面
Xib文件的加载:
方法1NSArray *objs = [NSBundle mainBundle] loadNibNamed:@“AppView”owner:nil options:nil];
方法2UINib *nib = [UINib nibWithNibName:@“AppView”bundle:[NSBundle mainBundle]];
NSArray *objs = [nib instantiateWithOwner:nil options:nil];
XIB & Storyboard
相同点:
1> 都用来描述软件界面
2> 都用Interface Builder工具来编辑
不一样点
1> Xib是轻量级的,用来描述局部的UI界面
2> Storyboard是重量级的,用来描述整个软件的多个界面,而且能展现多个界面之间的跳转关系
7. View的封装思路
========================================
1> 若是一个view内部的子控件比较多,通常会考虑自定义一个view,把它内部子控件的建立屏蔽起来,不让外界关心
2> 外界能够传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据
MVC:
controller(控制中心,大管家)
Model(数据模型,数据) View(视图,显示数据)
特征:
View上面显示什么东西,取决于Model
只要Model数据改了,View的显示状态会跟着更改
Controller负责初始化Model,并将Model传递给View去解析展现
UILabel的常见设置:
@property(nonatomic,copy)NSString *text;
@property(nonatomic,retain)UIFont *font;
@property(nonatomic,retain)UIColor *color;
@property(nonatomic)NSTextAlignment textAlignment;
UIFont:
建立方法:
+(UIFont *)systemFontOfSize:(CGFloat)fontSize;系统默认字体
+(UIFont *)boldSystemFontOfSize:(CGFloat)fontSize;粗体
+(UIFont *)italicSystemFontOfSize:(CGFloat)fontSize;斜体
UIButton的常见设置:
-(void)setTitle:(NSString *)title forState:(UIControlState)state;
-(void)setTitleColor:(UIColor *)color forState:(UIControlState)state;
-(void)setImage:(UIImage *)image forState:(UIControlState)state;
-(void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;
//设置按钮的文字字体
btn.titleLabel.font = [UIFont systemFontOfSize:13];
//得到按钮的文字
-(NSString *)titleForState:(UIControlState)state;
-(UIColor *)titleColorForState:(UIControlState)state;
-(UIImage *)imageForState:(UIControlState)state;
-(UIImage *)backgroundImageForState:(UIControlState)state;
新建
shift + cmd + n 新建项目
cmd + n 新建文件
视图
option + cmd + 回车 打开助理编辑器
cmd + 回车 显示主窗口
cmd + 0 导航窗口
option + cmd + 0 工具窗口
在.m & .h之间切换 control + cmd + 上/下
按照浏览文件的先后顺序切换 control + cmd + 左右
查看头文件 control + cmd + j
切换到对应的函数 control + 6 支持智能输入,注意输入法
运行
cmd + r 运行
cmd + . 中止
cmd + b 编译
cmd + shift + b 静态内存分析编译,能够检查程序结构上是否存在内存泄露
排版
control + i 将选中按钮从新缩进
cmd + ] 向右增长缩进
cmd + [ 向左减小缩进
cmd + / 注释/取消注释,提示:取消注释时,注释双斜线必须在行首
cmd + 向上 到文件开始位置
cmd + 向下 到文件末尾位置
.png格式的图片都是直接拖Applicon;
.jpg格式的图片放在Supporting Files。
序列帧动画,就是让一组图片一张一张顺序播放。
git的使用:
newBranch (不想改变破坏原来的版本,新建一个分支看看是否适合)
switch to branch 切换分支(查看原来的版本)
Merge from Branch 将原来版本和分支整合起来
0526
UIScrollView的基本使用:
1将须要展现的内容添加到UIScrollView
2设置UIScrollView的contentSize属性,告诉尺寸,也就是滚动范围
UIScrollView没法滚动的解决办法:
缘由:没有设置contentSize;
scrollEnabled = NO
没有接收到触摸事件:userInteractionEnabled = NO
没有取消autolayout功能
UIScrollView的代理
前提可以监听UIScrollView的整个滚动过程
就是给它设置一个代理对象,经过代理通知滚动过程
UIScrollView和delegate的通讯:
发送信息就是调用方法
1UIScrollView开始拖拽,调用scrollViewWillBeginDragging:方法通知delegate
2滚动某个位置,调用scrollViewDidScroll:方法
3中止拖拽,调用scrollViewDidEndDragging:willDecelerate:方法
称为delegate的条件:
遵照UIScrollViewDelegate协议,而后实现协议中的方法就能够了
UIScrollView和控制器:
通常设置UIScrollView所在控制器为UIScrollView的delegate
有2种方法:
经过代码
self.scrollView.delegate = self;
经过storyboard托线
UIScrollView的常见属性
@property(nonatomic)CGPoint contentOffset;//滚动位置
@property(nonatomic)CGSize contentSize;//滚动范围
@property(nonatomic)UIEdgeInsets contentInset;//设置滚动控件的四周增长额外的滚动区域
其余属性:
@property(nonatomic)BOOL bounces;//是否须要弹簧效果
@property(nonatomic,getter = isScrollEnabled)BOOL scrollEnabled;//是否能滚动
@property(nonatomic)BOOL showsHorizontalScrollIndicator;//是否显示水平滚动条
@property(nonatomic)BOOL showsVerticalScrollIndicator;
缩放
//用户使用捏合手势调用
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;
缩放实现步骤:
1设置UIScrollView的id<UIScrollViewDelegate>delegate对象
2设置minimumZoomScale:缩放最小比例
3设置maximumZoomScale:放大的最大比例
4让代理对象实现下面方法,返回须要缩放的视图控件
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;
跟缩放相关的其余代理方法:
//缩放完毕
-(void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view;
//正在缩放
-(void)scrollViewDidZoom:(UIScrollView *)scrollView;
分页:
pageEnabled属性设置YES,分页展现
UIPageControl的属性:
//一共多少页
@property(nonatomic)NSInteger numberOfPages;
//当前显示的页码
@property(nonatomic)NSInteger currentPage;
//只有一页时,是否须要隐藏页码显示器
@property(nonatomic)BOOL hidesForSinglePage;
//其余页码显示的颜色
@property(nonatomic,retain)UIColor *pageIndicatorTintColor;
//当前页码显示器的颜色
@property(nonatomic,retain)UIColor *currentPageIndicatorTintColor;
NSTimer:
定时器
在制定时间执行指定任务;每隔一段时间执行指定的任务
//开启定时任务
+(NSTimer *)scheduledTimerWithTimeInterval:(NSTimerInterval)ti
target:(id)aTarget
selector(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)yesOrNo;
//中止定时器工做
-(void)invalidate;
0524
状态栏:
设置状态栏的样式
(UIStatusBarStyle)preferredStatusBarStyle;
设置状态栏的可见性
-(BOOL)prefersStatusBarHidden;
Retina屏幕:就是高清视网膜屏幕
苹果4/4s 3.5inch 640*960
苹果5/5c/5s 4inch 640*1136
UIButton得到当前状态下文字,文字颜色,图片。
@property(nonatomic,readonly,retain)NSString *currentTitle;
0527
UITableview基本使用
实现表格数据展现,继承自UIScrollview,支持垂直滚动
如何展现数据
UITableView须要一个数据源(dataSource)来显示数据,任意类型对象
UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等
没有设置数据源的UITableView只是个空壳
凡是遵照<UITableViewDataSource>协议的OC对象,均可以是UITableView的数据源
分为两种格式:plain,group
1设置数据源
2向数据源查询有多少组,每组有多少行,每行有显示什么对象
3头标题和尾部标题的设置
控制状态栏是否显示:返回YES表明隐藏状态栏,NO相反
-(BOOL)prefersStatusBarHidden
tableView和数据源(先调用数据源才有下面方法)
//一共有多少组数据
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
//每一组有多少行数据
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//每一行显示什么内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath;
cell的简介:
UITableView的每一行都是一个UITableViewCell,经过dataSource的tableView:cellForRowAtIndexPath
:方法来初始化每一行
UITableViewCell内部有个默认子实图:contentView,它是UITableViewCell的父视图,显示辅助视图
辅助指示视图的做用是显示一个表示动做的图标,经过设置UITableViewCell的accessoryType来显示,
默认是UITableViewCellAccessoryNone
***还能够经过cell的accessoryView的属性自定义辅助指示视图(如往右边放一个开关)
UITableViewCell的contentView:
contentView下默认有3个子视图
其中2个是UILabel(经过UITableViewCell的textLabel和detailTextLabel属性访问)
第3个是UIImageView(经过UITableViewCell的imageView属性访问)
UITableViewCell还有一个UITableViewCellStyle属性,决定使用contentView的哪些子视图还有位置等
cell的重用原理:
当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中
,等待重用。当UITableView要求dataSource返回UITableViewCell时,datasource会先查看这个对象池,
若是池中又未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,而后返回给UITableView,从新显示到窗口中,从而避免建立新对象
自定义UITableViewCell时候,可能获得错误。怎么解决?
UITableViewCell有个NSString *reuseIdentifier属性,能够在初始化UITableViewCell
的时候传入特定字符串标识来设置reuseIdentifier,当UITableView要求dataSource返回UITableViewCell时,
先经过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,若是有就重用,没有就传入这个字符串标识
来初始化一个UITableViewCell对象
cell的重用代码:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
//定义一个cell的标识
static NSString *ID = @“MJCell”;
//从缓存池取出cell
UITableViewCell *cell = [tableview dequeueReusabelcellWithIdentifier:ID];
//若是缓存池没有cell
if(cell == nil){
cell = [UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:ID];
}
//设置数据
//返回cell
return cell;
}
cell的常见属性
设置cell的辅助视图:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
设置cell的背景颜色属性:默认状态下
cell.backgroundColor = [UIColor redColor];
//经过把backgroundColor和backgroundView均可以设置cell的背景'
不事后者比前者优先级高,颜色会覆盖前者颜色。
UIView*view=[[UIView alloc] init];
view.backgroundColor = [UIColor blueColor];
cell.backgroundView = view;
设置cell的选中状态背景的属性:
UIView*view=[[UIView alloc] init];
view.backgroundColor = [UIColor purpleColor];
cell.selectedBackgroundView = view;
tableview的常见属性(利用代码,不用storyboard)
(1)建立一个tableview
UITableview *tableview =[ [tableview alloc]init];
(2)设置数据源
tableView.datasource = self;
(3)添加tableview到view
[self.view addSubview:tableview];
(4)设置分割线样式
tableView.separatorStyle = UITableViewCellSeparatorStylenone;
(5)设置分割线颜色
24bit颜色(R,G,B);32bit颜色(A,R,G,B)
tableView.separatorColor = [UIColor colorWithRed:0/255.0 green:255/255.0 blue:0/255.0 alpha:255/255.0];
(6)设置tableview的头部尾部视图,不用设置宽度,默认和tableview宽度同样
tableView.tableHeaderView =[UIButton buttonWithType:UIButtonTypeContact add];
tableView.tableFooterView =[[UISwitch alloc] init];
Delegate的使用场合:
1对象A内部发生了一些事情,想通知对象B
2对象B想监听对象A内部发生了什么事情
3对象A想在本身的方法内部调用对象B的某个方法,而且对象A不能对对象B有耦合依赖
4对象A想传递数据给对象B
。。。。结果:对象B是对象A的代理。
使用delegate的步骤:
1搞清楚谁是谁的代理
2定义代理协议,协议名称的命名规范:控件类名 + delegate
3定义代理方法:
》代理方法通常定义为@optional
》代理方法名都以控件名开头
》代理方法至少有1个参数,将控件自己传递出去
4设置代理对象
》代理对象遵照协议
》代理对象实现协议里面该实现的方法
5在恰当时候调用代理对象的代理方法,通知代理发生了什么事情
自定义cell:
在系统自带中,cell中只有两个lable,一个image,知足不了需求,能够自定义cell
有2种方式:1经过纯代码 2经过xib(每一个cell都相同时候用xib)
****经过xib步骤自定义cell(iOS-USER interface-empty-next-名称XXXCell-creatre)
往xib里面拖拽所须要的控件,经过xib来描述一个cell;须要绑定一个ID标识
****使用xib封装一个cell的步骤:
1新建一个xib文件描述一个view/cell的内部结构
2新建一个自定义的类
3新建类的类名最好跟xib文件名保持一致
4将xib控件和自定义的.m文件进行连线
5提供一个类方法返回一个建立好的自定义cell
6提供一个模型属性让外界传递模型数据
7重写模型属性的setter方法,在这里将模型数据展现到对应的子控件上面
*****经过纯代码自定义cell(cell的高度不一致)
1新建一个继承自UITableViewCell的类
2重写initWithStyle:reuseIdentifier:方法
》添加全部须要显示的子控件(不须要设置子控件的数据和frame,子控件要添加到contentView中)
》进行子控件一次性的属性设置
3提供2个模型
》数据模型:存放文字数据\图片数据
》frame模型:存放数据模型\全部子控件的frame\cell的高度
4cell拥有一个frame模型
5重写frame模型属性的setter方法: 在这个方法中设置子控件的显示数据和frame
6frame模型数据的初始化以及采用懒加载的方式(只加载一次)
控件经过xib或者storyboard建立控件时候调用
-(void)awakeFromNib{
}
协议可选的optional。
协议名称:控件名称+delegate
协议方法名称:控件名称去掉前缀+含义
协议方法中将本身控件传出去的目的是发布用于区分哪一个空间触发类该方法
UITextField:
经过UITextFiel的代理方法可以监听键盘最右下角按钮的点击
//称为UITextField的代理
self.textField.delegate = self;
//遵照协议,实现代理方法
-(BOOL)textFieldShouldReturn:(UITextField *)textField;
//在UITextField左边放一个view
self.textField,leftView = [[UIView alloc]initWithFrame:CGRectMake(0,0,8,0)];
self.textField.leftViewMode = UITextFieldViewModeAlways;
数据独立:
iOS—》Cocoa Touch —>OC class
新建一个继承NSObject的类,创建一个模型保存数据
1建立模型
2将模型添加到数组中
3返回数组
取出对应的组模型
返回对应组行的数据
设置要显示的数据
**注意点:当每一行的cell的高度不一致时候就使用代理方法设置cell的高度
#warning待续,接着写(很好的做用)
如:
-(CGFloat)tableView:(UITableView *)tableView hightForRowAtIndexPath:(NSIndexPath *)indexPath;
1.tableView的刷新
1> 数据刷新的整体步骤
* 修改模型数据
* 刷新表格(刷新界面)
2> 刷新表格(刷新界面)的方法
* 全局刷新(每一行都会从新刷新)
- (void)reloadData;
* 局部刷新(使用前提: 刷新先后, 模型数据的个数不变)
- (void)reloadRows:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
* 局部删除(使用前提: 模型数据减小的个数 == indexPaths的长度)
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
2.@property属性的用法
* weak(assign) : 代理\UI控件
* strong(retain) : 其余对象(除代理\UI控件\字符串之外的对象)
* copy : 字符串
* assign : 非对象类型(基本数据类型int\float\BOOL\枚举\结构体)
0530
通知机制:
通知中心(NSNotificationCenter)
每个应用APP都有一个通知中心实例,负责协助不一样对象之间的消息通讯
任何一个对象均可以向通知中心发布通知,描述本身在作什么。
通知发布者 通知接收者
某个对象A ——发布通知—————>通知中心 observer1
某个对象D————————> observer2
通知包含的3个属性:
-(NSString *)name;//通知名称
-(id)object;//通知发布者
-(NSDictionary *)userInfo;//一些额外的信息(通知发布者传递给通知接收者的信息内容)
初始化一个通知对象:
1+(instancetype)notificationWithName:(NSString *)aName object:(id)anObject;
2+(instancetype)notificationWithName:(NSString *)aName object:(id)anObject userInfo:
(NSDictionary *)aUserInfo;
3-(instancetype)initWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo;
发布通知:
//发布通知,能够设置通知名称,通知发布者,额外信息
1-(void)postNotification:(NSNotification *)notification;
//发布一个名称为aName的通知,anObject为这个通知的发布者
2-(void)postNotificationName:(NSString *)aName object:(id)anObject;
//发布一个名称为aName的通知,anObject为这个通知的发布者,aUserInfo为额外信息
3-(void)postNotificationWithName:(NSString *)aName object:(id)anObject userInfo:
(NSDictionary *)aUserInfo;
注册通知监听器:
1-(void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName
object:(id)anObject;
observer:谁要接收这个通知
aSelector:收到通知后,回调监听器方法,并把通知对象当作参数传入
aName:通知名称
anObject:通知发布者
2
-(id)addObserverForName:(NSString *)name object:(id)obj queue:
(NSOperationQueue *)queue usingBlock:(void(^)(NSNotification *note))block;
name:通知名称
obj:通知发布者
block:收到对应通知后,回调这个block
queue:决定block在哪一个操做队列执行,传nil,默认在当前操做队列同步执行
取消注册通知监听器:
-(void)removeObserver:(id)observer;
-(void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;
通常在监听器销毁以前取消注册:
-(void)dealloc{
[super dealloc];//非ARC中须要调用
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
UIDevice通知:
UIDevice类提供了一个单例对象,表明设备,获取设备信息,如电池状态,设备类型,设备系统
经过[UIDevice currentDevice]能够获取这个单粒对象
UIDevice对象发布通知的名称常量:
UIDeviceOrientationDidChangeNotification//设备旋转
键盘通知:
UIKeyboardWillShowNotification//键盘即将显示
UIKeyboardDidShowNotification//键盘显示完毕
UIKeyboardWillHideNotification//
UIKeyboardDidHideNotification
UIKeyboardWillChangeFrameNotification//键盘位置尺寸即将发生改变
UIKeyboardDidChangeFrameNotification
UIKeyboardFrameBeginUserInfoKey//键盘刚开始的frame
UIKeyboardFrameEndUserInfoKey
UIKeyboardAnimationDurationUserInfoKey//键盘动画的时间
UIKeyboardAnimationCurveUserInfoKey//键盘动画的执行节奏
通知和代理的选择:
共同点:利用通知和代理都能完成对象之间的通讯
不一样点:
代理:一对一关系
通知:多对多关系
0603
pickerview 和tableview同样,也有数据源,不过须要用代理来显示数据,不是由数据源显示
tableview设置高度时候有两种方法:一种是属性。(每行高度同样)一种是代理
pickerView只有代理一种方法
一.UIPickerView
1.UIPickerView的常见属性
// 数据源(用来告诉UIPickerView有多少列多少行)
@property(nonatomic,assign) id<UIPickerViewDataSource> dataSource;
// 代理(用来告诉UIPickerView每1列的每1行显示什么内容,监听UIPickerView的选择)
@property(nonatomic,assign) id<UIPickerViewDelegate> delegate;
// 是否要显示选中的指示器
@property(nonatomic) BOOL showsSelectionIndicator;
// 一共有多少列
@property(nonatomic,readonly) NSInteger numberOfComponents;
2.UIPickerView的常见方法
// 从新刷新全部列
- (void)reloadAllComponents;
// 从新刷新第component列
- (void)reloadComponent:(NSInteger)component;
// 主动选中第component列的第row行
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated;
// 得到第component列的当前选中的行号
- (NSInteger)selectedRowInComponent:(NSInteger)component;
3.数据源方法(UIPickerViewDataSource)
// 一共有多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
// 第component列一共有多少行
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
4.代理方法(UIPickerViewDelegate)
// 第component列的宽度是多少
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;
// 第component列的行高是多少
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component;
// 第component列第row行显示什么文字
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
// 第component列第row行显示怎样的view(内容)
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
// 选中了pickerView的第component列第row行
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;
二.UIDatePicker
1.常见属性
// datePicker的显示模式
@property (nonatomic) UIDatePickerMode datePickerMode;
// 显示的区域语言
@property (nonatomic, retain) NSLocale *locale;
2.监听UIDatePicker的选择
* 由于UIDatePicker继承自UIControl,因此经过addTarget:...监听
Info.pilst常见的设置,是在Supporting files文件夹
pch文件也就是Supporting files的头文件,能够被全部源文件访问和使用
pch的常见使用:1用来定义一些全局的宏
2用来导入一些全局都能用到的文件
3用来自定义log
--objc--这个宏,只要在.M或者.MM才定义这个宏
在开发中有两个阶段:
1开发调试阶段:是须要打印LOG调试程序,系统定义一个叫作BEBUG的宏
2发布阶段:不须要打印LOG,由于LOG很占用资源而且用户看不懂
所以,自定义LOG就诞生了。
更简单的就是自动解开自动加:
在pch文件中
#ifdef BEBUG
#define Log(...) NSLog(__VA_ARGS__)
#else
#define Log(..)
#endif
当去公司的时候,作的第一件事就是观察公司自定义的LOG
UIApplication:
应用程序有一个openURL的强大功能。统一资源定位符,
用来惟一 的表示一个资源。表示一个资源地址
URL:协议头://主机地址/资源路径
网络资源:http://www.baidu.com/images/20140603/abc.png
本地资源:file:///users/apple/desktop/abc.png
http://ios.itcast.cn
UIApplication和delegate
全部移动操做系统都有个致命的缺点:app很容易受到打扰。
delegate可处理的事件包括:
1应用程序的生命周期事件(如程序启动和关闭)
2系统事件(如来电)
3内存警告
............
iOS程序的启动过程(没有storyboard)
1打开程序,执行main函数;
2执行UIApplicationMain函数;(建立UIApplication对象,建立UIApplication的delegate对象)
3delegate对象开始处理监听系统事件(没有storyboard)
*程序启动完毕时候会调用代理的application:didFinishlauchingwithoptions:方法
*在application:didFinishlauchingwithoptions:方法中建立UIWindow
*建立和设置UIWindow的rootviewController
*显示窗口
iOS程序的启动过程(有storyboard)
1打开程序,执行main函数;
2执行UIApplicationMain函数;(建立UIApplication对象,建立UIApplication的delegate对象)
3根据Info.plist得到主要storyboard的文件名,加载最主要的storyboard(有storyboard)
*建立UIWindow
*建立和设置UIWindow的rootviewController
*显示窗口
分析:UIApplicationMain函数会根据principalClassname建立UIApplicationMain
对象,根据delegateClassname建立一个delegate对象,并将delegate对象
赋值给UIApplication对象中的delegate属性;
而后创建程序的main runloop(事件循环),进行事件处理(在程序完毕后调用delegate对象
的application:didFinishlaunchingwithoptions:方法 )//通知代理
最后程序正常退出时UIApplicationMain函数才返回。
argc:系统或者用户传入的参数 个数;
argv:系统或者用户传入的实际参数。
int main (int argc, char * argv[]){
}
这个函数作了哪些事情?
1根据传入的第三个参数建立UIAoolication对象
2根据传入的第四个参数产生UIApplication对象的代理
3设置刚刚建立出来的代理对象为UIApplication的代理
4开启一个事件的循环,死循环,UIApplicationmain永远不会返还
UIWindow
是一种特殊的UIView,一个app只会有一个UIWindow
ios程序启动完毕后,建立第一个视图控件就是UIWindow,接着建立控制器的view,
最后将控制器的view添加到UIWindow上,因而控制器的view就显示在屏幕上了。
一个iOS程序之因此能显示到屏幕上,彻底是由于它有UIWindow,没有它,就看不见
UI界面了。
主窗口和次窗口的区别:
在iOS7之前,只有主窗口能够输入内容;
在iOS7之后,主窗口和次窗口均可以显示输入内容
控制器的多种建立方式:
1经过storyboard,(加载storyboard;建立storyboard箭头指向的控制器/或者经过惟一标示符)
2直接建立
NJViewController *nj =[ [NJViewController alloc]init];
3指定xib文件来建立
NJViewController *nj =[ [NJViewController alloc]initWithNibName :"NJViewController" bundle:nil];
控制器view的建立方式:
1//经过alloc init建立,会自动创一个空白的view作为控制器的view(没有storyboard和xib)
NJViewController *vc =[ [NJViewController alloc]init];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
2有storyboard的状况下建立
//经过storyboard,会根据storyboard中箭头指向控制器view的描述建立控制器的view
加载storyboard:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@""test bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];==
//UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"two"];
self.window.rootviewController = vc;
[self.window makeKeyAndVisible];
注意:若是有重写控制器loadview方法,就不会建立storyboard描述中的view,
,而是建立一个空白的view来做为控制器的view。
3经过指定xib建立
先设置一个view;根据xib描述的view来建立控制器的view
NJViewController *VC=[ [NJViewController alloc]initWithNibname:@“one” bundle:nil];
self.window.rootviewController = vc;
[self.window makeKeyandvisible];
4有同名xib建立,xib名称和控制器的名称相同
会自动找到同名xib中描述的view做为控制器的view
NJViewController *VC=[[ [NJViewController alloc]init];
self.window.rootviewController = vc;
[self.window makeKeyandvisible];
5有同名xib去掉controller状况下
会自动找到该xib的view做为控制器的view
NJViewController *VC=[[ [NJViewController alloc]init];
self.window.rootviewController = vc;
[self.window makeKeyandvisible];
6重写控制器loadview方法,就不会去加载建立同名去掉controller的xib和同名的xib
,而是建立一个空白的view来做为控制器的view
-(void)loadView{
self.view =[ [UIView alloc ]init];
}
最优先级方法,何时调用loadview方法就何时加载控制器的view
// 当控制器须要显示控制器的view的时候就会调用loadView
// 能够在loadView方法中建立view给控制器
// 该方法通常用于自定义控制器的view
控制器view的延迟加载---懒加载
能够用isViewloaded方法判断一个UIViewController的view
是否已被加载;
控制器的view加载完毕(也就是loadView方法完毕后)就会调用viewDidload方法
多控制器:父控制器,子控制器
管理控制器的特殊的控制器:
UINavigationController 和 UITabBarController
UINavigationController使用步骤:
1初始化UINavigationController
2设置UIWindow的rootController为UINavigationController
3根据具体状况,经过push方法添加对应个数的子控制器
UINavigationController是经过栈的形式来管理子控制器先进后出
UINavigationController的view结构:导航条;导航控制器的view;栈顶控制器的view;
显示在导航控制器上的view永远是栈顶控制器的view
返回就会将放在栈里面的控制器一个一个销毁,而后控制器的view也会跟着慢慢销毁
nav.viewController;//导航控制器的栈等效 nav.childviewController;
添加子控制器到导航控制器上:4种方法
1[nav.childviewController:one ];
2[nav pushviewController:one animated:YES];
3nav.viewControllers=@[one];赋值
4UINavigationController *nav =[[ UINavigationController alloc]initwithrootviewController:one];
怎么获取栈顶的控制器?方法
nav.topviewController;
移除当前栈顶控制器?方法
[self.navigationController popToViewController animated:YES];
怎么从最栈顶控制器回到最初的控制器?方法
[self.navigationController popTorootviewController animated:YES];
//zhi要传入栈的某一个控制器就好跳转到指定控制器 方法
[self.navigationController popToviewController:two animated:YES];
总结:一个导航控制器只有一个导航条,也就是说全部的子控制器都公用一个导航条
导航条上显示的内容和栈顶控制器有关,全部导航条上显示什么内容由栈顶控制器决定
怎么控制当前控制器对应的导航条显示的内容?方法
-(void)viewDidLoad(){
[super viewDidLoad];
self.navigationItem.title=@"";
}
注意导航条上显示的内容特例:导航条上的返回按钮的文字是由上一个控制器决定的
修改返回按钮显示的内容方法:
self .navigationItem.backBarButtonItem =[ [UIButtonItem alloc ]initWith
tittle:@"返回" styleBarbuttonItemstylepliantarget:nil action:bil] ;
控制器生命周期:
过期方法:(面试时候常常会问看你是否有经验)
//控制器即将销毁的时候调用
-(void)viewWillunload{
[super viewWillunload];
}
//控制器即将销毁的时候调用
-(void)viewDidunload{
[super viewDidunload];
}
接收到内存警告的时候调用
-(void)didreceivememoryWarning{
[super didreceivememoryWarning];
}
当系统出现内存警告的时候怎么处理?
首先,当系统出现memory warning的时候会调用didreceivememoryWarning这个方法,接着判断
是否有is there a view ?若是控制器有view就判断是否能销毁?怎么判断它是否能被销毁?控制器的view不在UIwindow上能够销毁,
而后会调用viewWillunload方法来即将释放控制器的view,接下会释放控制器的view,released the view,
再调用viewdidunload方法以后控制器的view已经被销毁了,可是数据还在,通常在viewwillunload清空不须要的数据,
当调用完这个方法以后,控制器的view和不须要的数据都被销毁了。
须要再次显示这个控制器的view?
loadView——>viewDidLoad——>viewWillAppear——>viewDidAppear——>
viewWillDisappear——>viewDiddisappear——>didReceivememoryWarning
——>viewWillUnload——>销毁view——>viewDidUnload——>(重复加载)loadView
0604
控制器的值传递:
顺传和逆传
顺传:从A到C;采起perform方法,取出目标控制器
逆传:从C到A;让A成为C的代理,设置数据模型方法
除了push以外,还有另一种控制器的切换方式,那就是Modal
任何控制器都能经过Modal形式展现,最底面钻出来
注意点:若是一个控制器的视图是以模态形式展示出来的,能够调用该控制器
以及该控制器的子控制器让控制器消失。
若是控制器之间的关系比较紧密用UINavigationController;
若是控制器之间的关系不是很紧密用Modal。
数据存储:
1plist属性列表(plist经过XML来保存数据),本质是XML,只存储系统自带的一些类如dictionary,array等
2preference(偏好设置/NSUserDefaults)
3键值归档(NSCoding/NSKeyedArchiver)
4SQLite3数据库
5Core Data
应用沙盒:
模拟器应用沙盒的根路径在:/Users/apple/Library/Application Support/iPone
Simulator/7.0/Applications
layer:是属于应用程序包,压缩包,不能存储任何东西
Documents:把重要文件存储在这里,持久化,会备份;
tep:保存临时数据;
Library/Caches:存储体积大,不须要备份的非重要数据;
Library/preference:存储应用的全部偏好设置。(系统自动放)
1XML属性列表(plist)归档(plist经过XML来保存数据)注意:不能保存自定义对象
获取应用程序沙盒目录方法:
NSString *home = NSHomeDictionary( ) ;
//动态获取数据
NSString *path =[NSSearchpathfordirectoriesindomains(NSdocumentdirectory,NSUserdomainmask,YES)lastobject];
//拼接文件路径
NSString *path = [doc stringByAppendingPathComponent:@"abc.plist”];
2偏好设置是专门用来保存应用程序的配置信息,通常状况下不用偏好设置中保存
其余数据,若是利用系统的偏好设置来存储数据,默认就是存储在preference文件夹下面
偏好设置会将全部数据保存到同一个文件中。本质是plist,不能保存普通对象
3文件归档:NSKeyedArchiver归档(NSCoding)保存自定义对象
若是想自定义对象保存到文件必须实现NSCoding协议,在协议中写清楚要存储哪些对象的属性
建立对象;
获取文件途径;
将自定义对象保存在文件中;
而后实现严格coding协议;
以什么方式保存就以什么方式读取。
0606
1.UISwitch
* UISwitch继承自UIControl,所以也能像UIButton同样监听一些事件,好比状态改变事件
* UISwitch能够经过拖线监听状态改变
* UISwitch能够经过addTarget:...方法监听状态改变
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
// 其中controlEvents参数传递的是:UIControlEventValueChanged(值改变事件)
2.监听文本框的文字改变
* 一个文本输入框的文字发生改变时,文本输入框会发出一个UITextFieldTextDidChangeNotification通知
* 所以经过监听通知来监听文本输入框的文字改变
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:textField];
// textField文本输入框的文字改变了,就会调用self的textChange方法
UIKit框架学习完毕**********
0607
Quartz2D来自Core Graphics 框架,纯C语言
Quartz 2D价值:自定义view/控件
注意自定义view的时候要重写initWithframe方法和initWithcoder方法。
图形上下文Graphics Context:是一个CGContextRef类型的数据
做用:
1 保存绘图信息(起点终点),绘图状态(颜色,线宽,线段顶部);
2 决定绘制的输出的目标
图形上下文有5种类型:window;layer;printer;PDF; Bitmap
若是在drawRect方法调用GraphicsGetcurrent Context方法获取
出来的就是layer的上下文。
画图的步骤:
获取上下文;
绘制图形;
渲染图形到layer上。
CGContextRef ctx = UIGraphicsgetcurrent Context;获取上下文
保存上下文图形
CGContextSaveGetState(ctx);
还原图形上下文
CGContextRestoreGetState(ctx);
rotate旋转;scale缩放;translate平移
图片剪切clip
自定义view的步骤:
1 新建一个类,继承UIView
2 实现-(void)drawRect:(CGRect)rect方法,而后在这个方法中
》 获取上下文;
》 绘制图形;
》利用上下文将绘制内容渲染显示到view上
drawRect:方法何时调用?
当view第一次显示到屏幕上时候调用;
调用view的setNeedsDisplay或者setNeedsDisplayInRect:时
Quartz2D的内存管理:
1有copy和create须要释放;
2retain了一个对象,再也不使用须要release;
3使用Quartz2D的函数来指定retain和release对象
4也可使用Core Foundation的CGRetain和CGRelease
KVC\KVO
KVC:键值编码 经过字符串更改对象属性,方法是valueForKey:和setValue:ForKey:
支持键路径key path,属性访问
KVO:键值监听
监听某个对象的属性
0609
如何建立一个Bitmap的上下文?
UIGraphicsBeginImageContextWithoptions(CGSize size,BOOL opaque,CGFloat scale);
步骤:
1 加载图片;
2 建立bitmap的上下文;
3 获取上下文;
4 绘图;
5 渲染;
6 获取生成的图片;
7 显示生成的图片到imageview;
8 保存绘制好的图片到文件中
水印的做用:图片从哪来的?主要是一些网站为了版权问题,广告而添加的
实现方式:利用Quartz2D,图片水印,文字水印
0610
swift的基本使用:在Xcode6以上使用
不须要main函数;不须要分号;支持多行注释嵌套多行注释;
常量和变量:
用let来声明常量;用var来声明变量;
常量和变量的命名:基本上能够用任何你喜欢的字符做为常量和变量
表情是一种特殊的Unicode字符
注意点:不能包含数学符号;不能包含箭头;不能包含非法无效的Unicode字符;
不能是关键字;不能包含横线,制表符;不能以数字开头;不能是单独一个下划线
数据类型:
经常使用的有Int,Float,Double,Bool,String,Character,Array,Dictionary
数据类型的首字母都是大写的。
如何指定?在常量和变量名后面加上冒号和类型名称
整数:分为2种,有符号和无符号
整数的最值:number.min/max;
整数的4种表示形式:十进制:没有前缀;
二进制:以0b为前缀;八进制:以0o为前缀;十六进制:0x为前缀
类型别名:typealias 和typed 同样的用法
浮点数:double和float可使用十进制和十六进制表示
事件传递:
从父控件传递自控件;
触摸事件不能接受的三种状况:
1隐藏;透明度为0;不接受用户交互。
响应者链条:由不少响应者连接在一块儿组合起来的一个链条;
什么是响应者?继承自Responder的对象;
上一个响应者:默认作法是将事件顺着响应者链条传递给上一个响应者;
如何判断当前响应者的上一个响应者是谁?
1判断当前响应者是不是控制器的view,若是是上一个响应者就是控制器的view;
2若是不是控制器的view,上一个响应者就是父控件。
一次完整触摸事件的传递相应的过程:
UIApplication,UIWindow,递归找到最适合处理的事件的控件,控件调用
touches方法,判断是否实现touches方法,没有实现默认将事件传递给上一个响应者,找到上一个响应者
响应者链条有什么用?
可让一个触摸事件发生的时候让多个响应者同时相应该事件
0612
CALayer的基本使用
UIView之因此你显示在屏幕上,彻底是由于它内部的图层(CALayer对象)
建立UIView对象时候,UIView内部会自动建立一个图层
若是
CALayer是定义在QuartzCore框架;能够跨平台。iOS和MAC OS X使用
UIColor,UIImage是定义在UIKit框架;不能,只能在iOS使用
CGImageRef,CGColorRef两种数据类型定义在CoreGraphics框架。能够
UIView能够处理用户的触摸事件,多一种功能,而CALayer不能够。
CALayer性能更高一些。
CALayer的属性:
宽度和高度
位置
描点
背景颜色
形变属性
CALayer的重要属性:position和anchorPoint(锚点)
用来设置CALayer在父层中的位置,以左上角为原点;
锚点绝对CALayer身上的那个点会在position属性所指的位置,以本身的
左上角为原点。
动画:
CAAnimation是全部动画对象的父类,不能直接使用,
CAPropertyAnimation是CAAnimation的子类,也是抽象类,要想建立动画对象,使用它的两个子类
:CABasicAnimation(从一个数值变到另外一个数值)和CAKeyframeAnimation(使用一个NSArray保存这些数值)
CAAnimationGroup也是CAAnimation的子类,能够保存一组动画效果。
CATransition也是CAAnimation的子类,用于作专场动画,提供移出屏幕和移入屏幕的动画效果
UIView动画:首尾式动画
block式动画
UIImageView的帧动画
*******建立核心动画(Core Animation)
1.1告诉系统执行什么动画;
1.2保存执行以后的状态
1.2.1执行以后不删除动画
1.2.2执行总监保存最新的状态
1.3设置动画时间
2添加核心动画
3设置动画类型
4平移,缩放,旋转
***关键帧动画:CAKeyframeAnimation
***转场动画:CATransitionCA
***组动画:AnimationGroup
0620
真机调试:
必须购买苹果开发者帐号。我的:99美圆,能够进行真机调试,将开发好的程序发布APPStore
发布到APPStore会进行最少一个礼拜的应用程序审核
企业:299美圆能够真机调试,不能把开发好的程序发布APPStore,直接将打开好的程序发布到网站上(非苹果网站)
真机调试的主要步骤:
1登录开发者主页
>1.1登陆开发者主页
http://developer.apple.com/membercenter/index.action
>1.2管理证书(前提:得花99¥或299¥加入开发者计划)
2生成cer证书:cer是一个跟电脑相关联的证书文件,让电脑具有真机调试的功能
》2.1添加cer证书
》2.2利用钥匙串生成cer签名请求文件
》2.3选择cer签名请求文件,生成而且下载cer证书
3添加APP ID:调试哪些app?
》3.1添加App ID
》3.2App ID的描述和所调试应用的Bundle ID
4注册真机设备:哪台设备须要作真机调试?
>4.1添加真机设备
》4.2利用Xcode查看真机设备的惟一标识(插上USB数据线)
》4.3填写设备名称和惟一标识
5生成MobileProvision文件:结合2,3,4生成一个手机规定文件
》5.1添加MobileProvision文件
》5.2选择App ID
>5.3选择cer证书
》5.4选择真机设备
》5.5填写MobileProvision文件名
》5.6下载MobileProvision文件
6导入cer,MobileProvision文件
苹果网站:developer.apple.com\cn
》6.1最终会获得2个文件:
cer文件:让电脑具有真机调试的功能
MobileProvision文件:哪台设备,哪些APP,哪台电脑须要作真机测试?
》6.2双击导入cer文件(能够打开钥匙串确认证书是否有效)
》6.3双击导入MobileProvision文件(打开Xcode,连接好真机)
》6.4打开任意程序,选择真机设别,点击运行
7替换旧的调试证书
有时候须要把项目里面配置的旧调试证书换掉
0623/0624
多线程:
进程含义:系统中正在运行的一个应用程序
每一个进程都是独立的,互不干扰。
(经过活动监视器能够查看Mac系统所开启的进程)
线程的含义:1个进程要想执行任务,必须得有线程
线程是进程的基本执行单元,一个进程(程序)全部任务都在线程中执行
线程的串行:1个线程中任务的执行是串行的,按顺序一个一个的执行多项任务
同一时间内,1个线程只能执行1个任务。
多线程的含义:1个进程能够开启多条线程每条线程能够并行(同时)执行不一样的任务
(进程至关于车间;线程至关于车间工人)
多线程的原理:
1同一时间,CPU只能处理1条线程,只要1条线程在工做
2多线程并发(同时)执行,实际上是CPU快速的在多线程之间调度(切换)
3若是CPU调度线程的时间足够快,就形成了多线程并发执行的假象
思考:若是线程很是很是多,会发生什么状况?
CPU在N多线程之间调度,CPU会累死,消耗大量的CPU资源
每条线程被调度在的频次会下降,线程执行效率下降
多线程的优缺点:
能适当提升程序的执行效率;能适当提升资源利用率。
缺点:开启线程须要占用必定的内存的空间;
线程越多,CPU在调度线程上的开销就越大;
程序设计更加复杂:好比线程之间的通讯,多线程的数据共享
多线程在ios开发中的应用:
什么是主线程:(UI线程)一个IOS程序运行以后,默认会开启1条线程,成为主线程或者UI线程
主线程的做用:
1显示或者刷新UI界面;
2处理UI事件;
主线程的使用注意:别将比较耗时的操做放到主线程中
//得到当前线程
NSThread current = [NSThread currentThread] ;
耗时操做的执行:将耗时操做放在子线程,后台线程,非主线程
iOS中多线程的实现方案:
pthread (posix):是一套适用的多线程的API,适用于Unix,Linux,Window等系统,跨平台,可移植,使用难度大
线程生命周期是程序员管理,几乎不使用,C语言
NSThread:更加面向对象,简单易用,可直接操做线程对象,OC语言。偶尔使用,程序员管理生命周期
GCD:替代NSThread等线程技术,充分利用设备的多核,C语言,常用,自动管理生命周期
NSOperation:基于GCD,比GCD多了一些更简单实用功能,使用面向对象,OC语言,常用,自动管理生命周期
NSThread:
一个NSThread对象就表明一条线程
1建立线程(先建立后启动):
NSThread *thread = [NSThread alloc ]initWithTarget:self selector:@selector(run) object:nil];
线程启动:[thread start];
线程一启动,就会在线程thread中执行self的run方法
其余建立线程的方式:(优缺点)
//建立线程后自动启动线程
[NSThread detachNewThreadSelector:@selector (run) toTarget:self withObject:nil];
//隐式建立并启动线程
[self performSelectorInBackground:@selector(run) withObject:nil];
主线程的相关用法:
+(NSThread *)mainThread;
-(BOOL)isMainThread;
+(BOOL)isMainThread;
线程的调度优先级:
+(double)threadPriority;
+(BOOL)setThreadPriority:(double)p;
-(double)threadPriority;
-(BOOL)setThreadPriority:(double)p;
调度优先级取值范围是0.0~1.0,默认0.5,值越大,优先级越高。
线程的名字:
-(void)setName:(NSString *)n;
-(NSString *)name;
线程的状态:
新建—start—>就绪—CPU调度当前线程或者CPU调度其余线程—>运行
——>阻塞(还有死亡状态)——>就绪
控制线程状态:
启动线程;
-(void)start;
阻塞线程;
+(void)sleepUntilDate:(NSDate *)date;
+(void)sleepForTimeInterval:(NSTimeInterval)ti;
强制中止线程(exit)一旦线程死亡了就不能再次开启任务
+(void)exit;
多线程的安全隐患:
1 1块资源可能被多个线程共享,发生数据错乱
多线程安全隐患解决:互斥锁(使用前提多条线程抢夺同一块资源)
互斥锁使用格式:
@synchronized(锁对象){//须要锁定的代码}
互斥锁的优缺点:能有效防止因线程抢夺资源形成的数据安全问题;
须要消耗大量 的CPU资源
相关专业术语:线程同步。意思是多条线程按顺序的执行任务,互斥锁就是使用了线程同步技术
原子和非原子属性:
1 atomic,原子属性,为setter方法加锁;
加锁原理:
@property(assign,atomic)int age;
-(void)setAge:(int)age
{
@synchronized(self){
_age = age;
}
}
2 nonatomic,非原子属性,不会为setter方法枷锁
原子和非原子属性非选择:
atomic。线程安全,须要消耗大量资源;
nonatomic,非线程安全,适合内存小的移动设备
iOS开发建议:
1全部属性都声明为nonatomic
2尽可能避免多线程抢夺同一块资源
3尽可能将加锁,资源抢夺的业务逻辑交给服务端处理,减小移动客户端的压力
线程间的通讯:
在1个进程中,线程每每不是孤立存在的,多个线程之间须要常常进行通讯
体现:
1个线程传递数据给另外1个线程;
在1个线程中执行完待定任务后,转到另一个线程继续执行任务
线程间通讯经常使用方法:
-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
-(void)performSelector:(SEL)aSelector OnThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
在子线程中经过联网下载图片,而后回到主线程显示图片
通讯交互过程:主线程(添加UIImageview,显示图片),
子线程(下载图片,下载完毕)
下载图片的方法:在本地应用图片下载是:UIImage *image = [UIImage imageNamed:@“”];
从网络上的图片下载:UIImage *image = [[UIImage imageWithData:(NSData *)];
2GCD:
Grand Central Dispatch,译为牛逼的中枢调度器
纯C语言,提供很是强大的函数
优点:1是苹果公司为多核的并行运算提出的解决方案
2自动利用更多的CPU内核
3自动管理线程的生命周期
4程序员只须要告诉GCD想要执行什么任务,不须要编写任何线程管理代码
GCD的核心和概念:任务和队列
任务:执行什么操做
队列:用来存听任务
GCD使用就2个步骤:
1 定制任务;
2 将任务添加到队列中
遵循FIFO原则:先进先出,后进后出
有2个函数执行任务:
同步方式:
dispatch_sync( dispatch_queue_t queue , dispatch_block_t block);两个参数
queue:队列;
block:任务
异步方式:
dispatch_async( dispatch_queue_t queue , dispatch_block_t block);两个参数
区别:
同步:在当前线程中;
异步:在另一条线程中
GCD队列的类型:
1并发队列 让多个任务并发执行,并发功能只有在异步才能执行
2串行队列 让任务一个接着一个执行
注意:同步和异步决定了要不要开启新线程
同步:在当前线程执行任务,不具有开启新线程的能力
异步:在新的线程执行任务,具有开启新线程的能力
并发和串行决定了任务的执行方式:
并发:多个任务并发同时执行
串行:一个任务执行完毕,再执行下一个任务
并发队列:
//得到全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT,//队列的优先级
0);
串行队列:2种途径
1使用dispatch_queue_create函数建立
2使用主队列
dispatch_queue_t queue = dispatch_get_main_queue();
线程间通讯实例:(异步并发队列中通讯)
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
//执行耗时的异步操做。。
dispatch_async( dispatch_get_main_queue(),^{
//回到主线程,执行UI刷新操做
});
});
延时执行:
2种方式
1调用NSObject方法
[self performSelector:@selector(run) withObject:nil afterDelay:2.0];
2使用GCD函数
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0 *
NSEC_PER_SEC)),dispatch_get_main_queue(),^{
//2秒后异步执行这里的代码
})
一次性代码:
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
//只执行1次的代码
})
//使用异步函数往并发队列中添加任务,开启多条线程
//使用异步函数往串行队列中添加任务,开启1条线程
//使用同步函数往并发队列中添加任务,不会开启新线程
//使用同步函数往串行队列中添加任务,不会开启新线程
注意:凡是函数各类带有create,copy,new,retain等字眼,都须要进行release
GCD的数据类型在ARC环境下不须要再作release
CF(core Foundation)的数据类型在ARC环境下还要进行release
******主队列是GCD自带的一种特殊的串行队列,任务放主线程执行,无论是放在同步仍是异步都不会开启新的线程
主队列使用同步函数任务没法执行。
GCD其余用法队列组:
有这么一种需求:首先分别异步执行2个耗时的操做,其次等2各异步操做都执行完毕再回到主线程执行操做
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),
^{
//执行1个耗时的异步操做
});
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),
^{
//执行1个耗时的异步操做
});
dispatch_group_notify(group,dispatch_get_main_queue(),^{
//回到主线程执行操做
});
单例模式(保证这个类永远只有一个对象):ARC和非ARC的实现
设计模式:多年软件开发,总结出来的一套经验、方法、工具
永远只放一次内存,alloc负责分配内存
好处:方便控制实例个数,节约系统资源
宏是放在头文件里面的
可使用宏判断是否为ARC环境:(兼容)
#if __has_feature(objc_arc)
//ARC
#else
//MRC
#endif
在ARC中这样写单例模式:定义一个类,AudioTool
在.h中写一个方法:
+(instancetype)shareAudioTool;
//在.m中保留一个全局的static的实例
定义全局变量(整个程序运行过程,只有1份)
static id _instance;
//初始化,加载资源一次
-(id)init
{
if(self = [super init]){
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
//加载资源
});
return self;
}
重写控制内存方法,建立惟一的实例:alloc分配内存1次
+(id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
提供一个类方法让外界访问惟一的实例:
+(instancetype)sharedAudioTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [[self alloc]init];
});
return _instance;
}
//实现copyWithZone:方法
+(id)copyWithZone:(struct _NSZone *)zone
{
return _instance;//返回对象,不能返回类如self
}
非ARC这样写单例模式的代码:
和上面同样只是多了一些方法:
//实现内存管理方法:
-(oneway void)release{}//用在MAC上,分布式对象
-(id)autorelease{return _instance;}
-(id)retain{return _instance;}
-(NSUInteger)retainCount{return 1;}
单例模式的做用:保证程序运行过一个类只有一个实例,该实例易于供外界访问
方便控制实例个数,节约系统资源
使用场合:在整个应用程序,共享一份资源
单例模式在ARC和MRC环境写法不一样,须要编写2套不一样的代码
3NSOperation基本使用:
做用:配合NSOperation和NSOperationQueue也能实现多项线程编程
具体步骤:
1将须要执行的操做封装到一个NSOperation对象
2将NSOperation对象添加到NSOperationQueue中
3系统会自动将NSOperationQueue中的NSOperation取出来
4将取出的NSOperation封装的操做放到一条新线程中执行
NSOperation的子类:
NSOperation是个抽象类。并不具有封装操做的能力,必须使用它的子类
子类方式有3种:
1NSInvocationOperation
2NSBlockOperation
3自定义子类继承NSOperation,实现内部相应的方法
1NSInvocationOperation:
//建立NSInvocationOperation对象
-(id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
//调用start方法开始执行操做
-(void)start;
注意:调用start方法不会开启新线程执行操做,而是在当前线程同步执行操做
只有将NSOperation放到一个NSOperationQueue才会异步执行操做
2NSBlockOperation
//建立NSBlockOperation对象
+(id)blockOperationWithBlock:(void(^)(void))block;
//经过addExecutionBlock:方法添加更多的操做
-(void)addExecutionBlock:(void(^)(void))block;
注意:只要NSBlockOperation封装的操做数>1,就会异步执行操做
3NSOperation
NSOperation能够调用start方法来执行任务,可是默认是同步执行。若是将NSOperation添加到NSOperationQueue中,系统会自动异步执行。
添加操做到NSOperationQueue中:
-(void)addOperation:(NSOperation *)op;
-(void)addOperationWithBlock:(void (^)(void))block;
最大并发数:
同时执行的任务数
相关方法:
-(NSInteger)maxConcurrentOperationCount;
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
队列的取消,暂停,恢复
//取消队列的全部操做
-(void)cancelAllOperation;
//暂停和恢复队列:
-(void)setSuspended:(BOOL)b;
-(BOOL)isSuspended;//YES表明暂停,NO表明恢复
操做优先级:
改变操做的执行顺序
-(NSOperationQueuePriority)queuePriority;
-(void)setQueuePriority:(NSOperationQueuePriority)p;
操做依赖:设置依赖来保证执行顺序
能够在不一样的队列的NSOperation之间建立依赖关系,不能相互依赖
操做的监听:
自定义NSOperation:
自定义NSOperation下载图片思路:
图片的URL:http://abc.png
怎么保证一个URL图片不重复下载?
SDWebImage框架用来下载图片,下载一个dng文件搜索WDWebImage这个框架
若是公司作的项目须要下载图片的话能够下载SDWebImage框架来使用
重点掌握NSOperationQueue;设置依赖;最大并发数设置;自定义NSOperation的基本流程
自定义NSOperation:
1重写=(void)main方法,在里面实现想执行的任务
注意:本身要建立自动释放池,若是是异步操做,没法访问主线程的自动释放池,经过-(BOOL)isCanceled方法检测操做释放被取消,对取消作出响应
总结多线程:
多线程
1.NSThread
1> 开线程的几种方式
* 先建立,后启动
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
* 直接启动
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
[self performSelectorInBackground:@selector(run) withObject:nil];
2> 其余用法
NSThread *current = [NSThread currentThread];
+ (NSThread *)mainThread; // 得到主线程
3> 线程间通讯
performSelectorOnMainThread.....
2.GCD(重点)
1> 队列的类型
* 并发队列
得到全局的并发队列: dispatch_get_global_queue
* 串行队列
a.本身建立
dispatch_queue_create
b.主队列
dispatch_get_main_queue
2> 执行任务的方法类型
* 同步(sync)执行
* 异步(async)执行
3> 了解队列和方法的配合使用
4> 线程间通讯
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操做...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操做
});
});
5> 其余用法
dispatch_once
dispatch_after
dispatch_group_async\dispatch_group_notify
3.NSOperation
1> 基本使用
NSInvocationOperation
NSBlockOperation
2> NSOperationQueue(重点)
* 最大并发数设置
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
* 设置依赖(面试题)
[operationB addDependency:operationA]; // 操做B依赖于操做A
3> 自定义Operation(了解基本流程)
4> 如何解决一张图片(一个url)重复下载的问题(面试题)
0626-0701
网络编程:
必须掌握的基本概念:
1客户端(移动应用)Client
2服务器(后端)server
3请求 request
4响应 response
服务器:
分为远程服务器(外网正式服务器)如:www.baidu.com(访问的是外网的服务器)
使用阶段:应用上线后使用的服务器
使用人群:供全体用户使用
速度:服务器性能,用户的网速
本地服务器(也叫内网,测试服务器)
使用阶段:应用处于开发测试阶段
使用人群:供公司内部开发人员,测试人员使用
速度:局域网,速度飞快
访问本地服务器的主机地址:3种写法
127.0.0.1:每一台机器内置的IP地址,机器自己(也是网卡IP地址)全部电脑和手机都有这个IP地址
localhost:等价于第一种状况
交换机\路由器的IP地址192.168.5.102:真机测试必定使用,并且真机和服务器都得在同一个局域网
如何访问本地服务器?
IP地址+端口+资源路径
如:192.168.5.102:8080/MJServer/
服务器的用处:提供登陆接口;提供资源
URL:Uniform Resource Locator统一资源定位符
经过1个URL,能找到互联网惟一的1个资源,URL就是资源的地址,位置
URL的基本格式 = 协议://主机地址(huo域名)/路径
如:http://ios.itcast.cn/ios/images/contenet_25.jpg
http://www.baidu.com/img/bdlogo.gif
URL常见协议:协议不同,访问资源的方式就不同
HTTP 超文本传输协议(什么东西均可以访问) 最经常使用访问远程网络资源,格式http://
File 访问本地计算机上的资源,格式:File://(不加主机地址)
mailTo访问电子邮件地址 格式是mailTo:
FTP访问共享主机的文件资源,格式是ftp://
HTTP协议的做用:遵照HTTP协议
1全称是Hypertet transfer Protocol,超文本传输协议
规定客户端和服务器之间的数据传输格式
让客户端和服务器能有效地进行数据沟通
HTTP的特色:简单快速;灵活;使用非连续
HTTP的完整通讯过程:
1请求:客户端向服务器索要数据
2响应:服务器返回客户端相应的数据
****HTTP的通讯过程——请求
请求:客户端向服务器索要数据
HTTP协议规定:客户端向服务器请求须要包含如下内容:
请求行:包含请求方法,请求资源路径,HTTP协议版本 如GET/MJServer/resource/images/1.jpg HTTP/1.1
请求头:包含对客户端的环境描述,客户端请求的主机地址等信息以下
Host:客户端想访问的服务器主机地址如192.168.1.105:8080
User-Agent:客户端类型,软件环境(pc端仍是移动端?)
Accept:客户端接收的数据类型 text/html,*/*
Accept-language:客户端语言环境 zh-cn
Accept-Encoding:客户端支持的数据压缩格式 gzip
请求体:客户端发给服务器的具体数据 好比文件数据
*****HTTP的通讯过程——响应
响应:服务器返回客户端相应的数据
HTTP协议规定,1个完整的HTTP响应包含如下内容:
状态行:包含了HTTP协议版本,状态码,状态英文名称 HTTP/1.1 200 OK
响应头:包含了对服务器的描述,对返回数据的描述
server:服务器的类型 Apache-Coyote/1.1
content-Type:返回数据的类型 image/jpeg
content-Length:返回数据的长度 56811字节
Date:响应的时间 Mon,23 Jun 2014 12:54:52 GMT
实体内容:服务器返回客户端的具体数据 好比文件数据
HTTP通讯过程:
请求行,请求头,请求体
客户端 ————————————> 服务器
<———————————
状态行,响应头,实体内容
常见响应状态码:
200:OK 请求成功
400:Bad Request 客户端请求语法错误,服务器没法解析
404:Not Found 服务器没法根据客户端的请求找到资源
500:Internal Server Error 服务器内部错误,没法完成请求
发送HTTP请求的方法有8种:GET(查),POST(改),PUT(增),DELETE(删)。。。。。
GET和POST对比:
区别在数据传递上
GET:在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开
POST:发给服务器的参数所有放在请求体中
GET和POST的选择:
若是要传输大量数据,好比文件上传,只能用POST请求
GET的安全性比POST差些,若是包含机密或者敏感信息,用POST
若是仅仅是索取数据(数据查询)用GET
若是是增长,修改,删除数据,用POST
iOS中发送HTTP请求的方案:
1NSURLConnection
2NSURLSession
3CFNetwork
4第三方框架:ASIHttpRequest(已经中止更新);AFNetworking
ASI和AFN架构对比:ASI性能比较好
NSURLConnection经常使用类:
(NSURLConnection-GET请求:请求行,请求头,没有请求体,因为苹果帮咱们弄好了前二者,所因此咱们只要写URL)
NSURL:请求地址
NSURLRequest:表明一个请求
NSURLConnection:负责发送请求,创建客户端和服务器的连接
发送NSURLrequest的数据给服务器,并收集来自服务器的响应数据
NSURLConnection的使用步骤:
1建立NSURL对象,设置请求路径
2传入NSURL建立一个NSURLRequest对象,设置请求头和请求体(iOS中的请求头和请求体通常不用设置,苹果原生自带)
3使用NSURLConnection发送NSURLRequest
NSURLConnection发送请求:
同步请求(一直在等服务器给数据,在当前线程也就是主线程)不建议使用
+(NSData *)sendSynchronousRequest:(NSURLRequest *)request
returningResponse:(NSURLResponse **)response error:(NSError **)error;
异步请求分为2种:
block回调//当请求结束时候调用(请求超时/请求失败)
+(void)sendSynchronousRequest:(NSURLRequest *)request
queue:(NSOperationQueue*)queue
completionHandler:(void(^)(NSURLResponse* response,NSData*data,NSError* connectionError))
handler;
代理:
-(id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+(NSURLConnection*)connectionWithRequest:(NSURLRequest*)request delegate:(id)delegate;
-(id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;
-(void)start;//异步请求
称为NSURLConnection的代理,遵照NSURLConnectionDataDelegate协议
NSURLConnectionDelegate:(遵照协议,还要实现4种办法)
//开始接收到服务器响应时调用 初始化数据
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response;
//接收到服务器返回 的数据时调用 收集数据
-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data;
//服务器返回的数据彻底接收完毕后调用 处理服务器全部数据
-(void)connectionDidFinishLoading:(NSURLConnection*)connection;
//请求出错时调用 请求超时/断网/网速慢
-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error;
NSMutableURLRequest:
经常使用设置有:timeoutInterval 请求超时等待时间
-(void)setTimeoutInterval:(NSTimeInterval)seconds;
HTTPMethod 请求方法
-(void)setHTTPMethod:(NSString*)method;
HTTPBody 请求体
-(void)setHTTPBody:(NSData*)data;
设置请求头
-(void)setValue:(NSString*)value forHTTPHeaderField:(NSString*)field;
建立GET和POST请求
建立GET请求
NSString *urlStr = [NSString stringWithFormat:@“http://192.168.1.102:8080/MJServer/login?username=123&pwd=123”,username,pwd];
NSURL *url = [NSURL urlWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//发送请求(异步请求)
建立POST请求
//设置请求路径
NSString *urlStr = [@“http://192.168.1.102:8080/MJServer/login“;
NSURL *url = [NSURL urlWithString:urlStr];
//建立请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @“POST”;
//请求体
NSString *bodyStr = @“username=123&pwd=123”;
request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
提交用户的隐私数据
必定要使用post请求提交用户的隐私数据;GET请求的全部参数都之直接暴露在URL中
数据安全:post请求提交用户的隐私数据还不能彻底解决安全问题
能够利用Charles设置代理服务器软件,拦截网络请求,利用Charles能得知大部分公司APP数据来源和数据格式
下载地址:http://www.charlesproxy.com/download
提交用户的隐私数据用暗文
常见的加密算法:
MD5\SHA\DES\3DES\RC2和RC4\RSA\IDEA\DSA\AES
MD5:Message Digest Algorithm5,译为消息摘要算法第5版
对输入信息生成惟一的128位散列值(32个字符串)
MD5特色:根据输出值不能得出原始明文,其过程是不可逆的
输入两个不一样的明文不会获得相同的输出值
应用:MD5解密网站:http://www.cmd5.com
MD5已经再也不是绝对安全了,要稍微改进
MD5改进:
加盐,就是在密码加一字符串
先加先加密,后乱序
JSON和XML(服务器为何返回JSON,是为了规范)
JSON是一种数据格式,用于用户交互
通常服务器返回客户端的数据,通常是JSN格式或者XML格式
NSJSON解析方案:有四种
JSONKit;第三方框架(性能好)
SBJSON;第三方框架(性能较好)
TouchJSON;第三方框架(性能差)
苹果原生:NSJSONSerialization(性能最好)用这个
NSJSONSerialization常见方法
JSON数据转换OC对象
+(id)JSONObjectWithData:(NSData*)data options:(NSJSONReadingOptions)opt error:(NSError*)error;
//OC对象转换JSON数据
+(NSData*)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError*)error;
XML格式:
Extensible Markup Language 译为可扩展标记语言
跟JSON同样,也是经常使用的一种用于交互的数据格式
通常叫XML文档(XML Document)
XML语法:
组成部分:文档声明;元素(Element),包含开始标签和结束标签;属性(Attribute)
同一份数据,既能够用JSON来表示;也能够用XML来表示
JSON体积小于XML。
XML的解析
XML的解析方式:
DOM:一次性将整个XML文档加载进内存,适合解析小文件
SAX:从根元素开始,按顺序一个元素一个元素往下解析,适合解析大文件
iOS中XML解析手段:
苹果原生
1NSXMLParser:SAX方式解析使用简单;
第三方框架:
2libxml2:纯C语言,默认包含在iOS SDK中国,同时支持DOM和SAX方式解析
3GDataXML:DOM方式解析,由google开发,基于libxml2,须要作配置:1导入libxml2库 2设置libxml2的头文件搜索路径
GDataXML的使用:
GDataXMLDocument:表明整个文档
GDataXMLElement:表明文档中的每一个元素
XML解析方式的选择建议:
大文件:NSXMLParser,libxml2
小文件:GDataXML
文件上传下载:
小文件下载:
1直接用NSData的+(id)dataWithContentsOfURL:(NSURL*)url;
2利用NSURLConnection发送一个HTTP请求下载
3若是是下载图片,能够利用SDWebImage框架
网络编程总结:
HTTP协议
1.面试题: 聊一下HTTP协议(协议的完整的通讯过程)
2.通讯过程
1> 请求
* 客户端 --> 服务器
* 请求的内容
a. 请求行(请求方法\HTTP协议\请求资源路径)
b. 请求头(描述客户端的信息)
c. 请求体(POST请求才须要有, 存放具体数据)
2> 响应
* 服务器 --> 客户端
* 响应的内容
a. 状态行(响应行, 状态码)
b. 响应头(服务器信息, 返回数据的类型, 返回数据的长度)
c. 实体内容(响应体, 返回给客户端的具体内容)
3.HTTP请求的方法
1> GET(不须要请求体)
* 参数都拼接在URL后面
* 参数有限制
2> POST
* 参数都在请求体
* 参数没有限制
4.iOS中发送GET\POST请求的手段
1> NSURLConnection
* 发送一个同步请求
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
* 发送一个异步请求
+ (void)sendAsynchronousRequest:(NSURLRequest*) request
queue:(NSOperationQueue*) queue
completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler;
* 代理的方法(异步)
[NSURLConnection connectionWithRequest:request delegate:self];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[conn start];
ASI和AFN的区别:
1性能
ASI基于底层的CFNetwork框架
AFN基于NSURLConnection
运行性能:ASI>AFN
2处理服务器数据
1>AFN
根据服务器返回数据进行自动解析
*服务器返回的是JSON数据,自动转换为NSDictionary或NSArray
*服务器返回的是XML数据,自动转换为NSXMLParser
2>ASI
并无对服务器数据进行解析,直接返回NSData二进制数据
3处理请求过程
AFN:success和failure两个block
ASI:有三种方式处理请求过程(代理、SEL、block)
ASI的特点:
1缓存
2下载和上传
*轻松监听请求进度
*轻松实现断点下载
3提供不少扩展接口(好比作数据压缩)
*ASIDataCompressor.h
*ASIDataDecompressor.h
4ASIHttPRequest继承自NSOperation
*能用队列统一管理全部请求
*请求之间能依赖
5ASINetworkQueue
*统一管理全部请求
*监听全部请求的开始或失败或完毕
AFN的特点:
1使用简单
2自带网络监控功能
643055886@qq.com
ios4762450
*****新浪微博一项目之大,从哪里开始作起?1项目组》移动开发组(移动iOS和安卓)》服务器(web)开发组(我发什么给你,你传什么给我?) 移动开发组———接口文档(沟通)———服务器开发组》产品需求组》测试组》美工组2项目文档》需求文档》接口文档》开发文档》产品文档3项目架构》UI界面层》业务类层》网络处理层》工具类层4分配任务》按照功能和模块来分》按照项目架构的层次分2、项目里面的用户微博数据从何而来?新浪的开发数据》新浪已经开发了用户的部分数据》新浪已经向开发者提供数据接口》开发者微博客户端发送HTTP请求到新浪的服务器,便可得到数据3、项目里面的UI素材从何而来?》正规的公司里面都会有专业的美工来切图》若是没有美工切图,能够暂用别人项目的素材 》从网上下载新浪的ipa安装包 》解压ipa包,取出里面的UI素材