學習了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素材