218.241.181.202 wxhl60 123456
192.168.10.253 wxhl66 wxhl66
CSDN論壇
github
cocoachina
code4app
拉勾網(wǎng)
友盟
Boss
shareSDK
CoreImage 內(nèi)置的濾鏡
融云 www.rongcloud.cn
{
目錄:
??、iOS 開發(fā)入門
??、視圖與窗口
??、AVAudioPlayer
??、多線程
??、GCD(Grand Central Dispatch) 隊列
??、網(wǎng)絡(luò)編程
??、繪圖與文本
??、正則表達式
??、沙盒路徑
??、CALayer
??、核心動畫
??、睡眠
??、UIImagePicker 和 相冊
??、觸摸
??、手勢
??、多媒體
??、block
??、添加字體
??、常用控件
??、視圖控制器
??、導(dǎo)航控制器
??、標簽控制器
??、滑動視圖
??、Sqlite數(shù)據(jù)庫
??、表視圖
??、UICollectionView 集合視圖
??、視圖控制器的側(cè)滑 MMDrawController
??、超文本鏈接
??、Foundation框架
??、GPS和地圖
??、MBProhressHUD 風火輪、活動監(jiān)視
??、富文本專輯
??、引導(dǎo)界面
??、CoreImage
??、宏定義那件小事
??、UIApplication
??、C語言常用函數(shù)
??、cocoapods安裝
??、發(fā)起通電
}
==================================================================================================================================================
》》》OC知識
成員變量,有三種權(quán)限,就是大家都知道的@private、@protected、@public?,寫在.m文件中時,相當于是@private權(quán)限,子類無法訪問,驗證了一下,做權(quán)限修改也無效。而寫在.h文件中,默認是@protected權(quán)限,子類可以訪問,可以做權(quán)限修改。
使用@property聲明的變量實際上就如在.m文件中聲明的變量一樣,是真正私有化的,@property聲明的變量做了三件事
1.在.ml文件中聲明一個@private的變量(不是在.h文件中聲明@private變量)
2.聲明setter和getter方法
3.定義setter和getter的實現(xiàn)
使用@property聲明的變量,子類是不能繼承的,分類是不能直接訪問的
==================================================================================================================================================
{
iOS初級
??、iOS 開發(fā)入門
一、iOS概述
1.iOS于2007年9月1日發(fā)布,和Mac OS X都基于UNIX系統(tǒng)
2.蘋果公司每年都會召開開發(fā)者大會(WWDC),期間會發(fā)布最新iOS系統(tǒng)版本
3.iOS架構(gòu)四個層次:可觸摸層(cocoa touch)、媒體層(media services)、核心服務(wù)層(core services)、核心操作系統(tǒng)層(core OS)
4.項目信息? ? Product Name :? ? 項目名
Organization Name : 公司名
Organization Identifier : 倒置后的網(wǎng)址
Bundle Identifier : 唯一標識符
Language : 開發(fā)語言
Dvices : 運行的設(shè)備
5.UI(user interface)
6.二倍圖片 @2x? ?三倍圖片 @3x? png類型的圖片可以省略格式
7.APP圖標尺寸 60*60
8.修改APP名:Info.plist -> Add Row -> Bundle Display Name
9.尺寸與分辨率? ? ?尺寸? ? 寬*高? ? ? ? 分辨率
3.5? ? 320*480? ? ? ? 640*960
4.0? ? 320*568? ? ? ? 640*1136
4.7? ? 375*667? ? ? ? 750*1334
5.5? ? 414*736? ? ? ? 1242*2208
10、導(dǎo)航欄44px? ? 狀態(tài)欄20px? ? 標簽欄49px
獲取設(shè)備信息
UIDevice *device = [[UIDevice alloc] init];
NSString *name = device.name;? ? ? //獲取設(shè)備所有者的名稱
NSString *model = device.name;? ? ? //獲取設(shè)備的類別
NSString *type = device.localizedModel; //獲取本地化版本
NSString *systemName = device.systemName;? //獲取當前運行的系統(tǒng)
NSString *systemVersion = device.systemVersion;//獲取當前系統(tǒng)的版本
}
==================================================================================================================================================
{
??、視圖與窗口
一、窗口 一方面提供一個區(qū)域來顯示視圖,另一方面將事件分發(fā)給視圖
//1、獲取當前設(shè)備屏幕對象
UIScreen *screen = [UIScreen mainScreen];
//2、用對象的位置、大小創(chuàng)建窗口
_window = [[UIWindow alloc] initWithFrame:screen.bounds];
//3、給窗口背景添加顏色
_window.backgroundColor = [UIColor blueColor];
//4、設(shè)置窗口的根視圖控制器
[_window setRootViewController:[[UIViewController alloc] init]];
//5、顯示窗口
[_window makeKeyAndVisible];
//設(shè)置優(yōu)先級
_window.windowLevel = UIWindowLevelAlert;? ? ? ?//設(shè)置窗口優(yōu)先級? ?會把狀態(tài)欄遮住
二、視圖
1、alpha 不透明度,小于0.01的視圖不接受點擊事件
(重要)2、clipsToBounds 默認是NO,當設(shè)置為yes時,超出當前視圖的尺寸的內(nèi)容和子視圖不會顯示。layer.cornerRadius
3、hidden 是否隱藏,默認是NO
4、userInteractionEnabled 是否開啟用戶交互,默認是YES(UIImageView默認是NO)
5、tag 視圖的標簽值,默認是0,建議設(shè)置在100以上,根據(jù)這個值可以在父視圖中查找該視圖,(默認值是0啊笨蛋)
6、exclusiveTouch 默認為No,exclusiveTouch的意義在于:如果當前設(shè)置了exclusiveTouch的UIView是整個觸摸事件的第一響應(yīng)者,那么到你所有的手指離開屏幕前其他的UIView是無法接受到整個事件周期內(nèi)所有的觸摸事件。
7、frame 位置和尺寸
8、center 中心點
9、bounds 只能修改尺寸
10、transform 形變狀態(tài)(平移、旋轉(zhuǎn)、縮放),帶make以原始形態(tài)進行改變,不帶make則以指定形態(tài)進行改變
11、superview 父視圖(只讀)
12、subviews 子視圖(數(shù)組)
13、window 所在窗口(只讀)
(重要)獲取根視圖的superview和window時,需要注意,在viewdidload中是獲取不到的,viewdidload只是視圖加載完成,并沒有添加到窗口中,因此需要在viewDidAppear方法中才能獲取到。那時候視圖才被添加到窗口中。
14、autoresizesSubviews 默認為YES,表示當父視圖尺寸改變時,子視圖也會隨著改變,默認值是YES
15、autoresizingMask 默認為UIViewAutoresizingNone,不會自動伸縮。
16、contentMode 設(shè)置內(nèi)容模式
UIViewContentModeScaleToFill? 不等比填充滿
UIViewContentModeAspectToFill? 等比填充滿,溢出
UIViewContentModeAspectToFit? 等比,留白
17、backgroundColor 背景顏色,默認是nil
18、添加子視圖方法 addSubview:? bringSubviewToFront:? sendSubviewToBack:? removeFromSuperview? insertSubview:atIndex:
insertSubview:aboveSubview:? insertSubview:belowSubview:? exchangeSubviewAtIndex:withSubviewAtIndex:
19、是否裁剪超出視圖部分當子視圖
view.clipsToBounds = YES;layer.cornerRadius
三、生命周期
1、創(chuàng)建載入跟視圖 loadView
2、視圖載入完成 viewDidLoad
3、視圖將出現(xiàn)在屏幕之前 viewWillAppear
4、視圖已經(jīng)在屏幕上渲染完成 viewDidAppear
5、視圖將要在窗口上移除之前 viewWillDisappear
6、視圖已經(jīng)從屏幕上移除 viewDidDisappear
7、接受到內(nèi)存警告
}
UIView的部分圓角問題
UIView?*view2?=?[[UIView?alloc]?initWithFrame:CGRectMake(120,?10,?80,?80)];
view2.backgroundColor?=?[UIColor?redColor];
[self.view?addSubview:view2];
UIBezierPath?*maskPath?=?[UIBezierPath?bezierPathWithRoundedRect:view2.bounds?byRoundingCorners:UIRectCornerBottomLeft?|?UIRectCornerBottomRight?cornerRadii:CGSizeMake(10,?10)];
CAShapeLayer?*maskLayer?=?[[CAShapeLayer?alloc]?init];
maskLayer.frame?=?view2.bounds;
maskLayer.path?=?maskPath.CGPath;
view2.layer.mask?=?maskLayer;
//其中,
byRoundingCorners:UIRectCornerBottomLeft?|?UIRectCornerBottomRight
//指定了需要成為圓角的角。該參數(shù)是UIRectCorner類型的,可選的值有:
*?UIRectCornerTopLeft
*?UIRectCornerTopRight
*?UIRectCornerBottomLeft
*?UIRectCornerBottomRight
*?UIRectCornerAllCorners
==================================================================================================================================================
{
??、AVAudioPlayer
注意:
1.需要導(dǎo)入#import
2.定義的對象需要定義成全局
一、AVAudioPlayer的使用,只能播放本地音視頻
1、獲取路徑
NSString *urlPath = [[NSBundle mainBundle] pathForResource:@"test.mp3" ofType:nil];
2、將路徑轉(zhuǎn)化成URL
NSURL *url = [NSURL URLWithString:urlPath];
3、實例化播放器(全局)
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
4、準備播放
[_audioPlayer prepareToPlay];
5、播放
[_audioPlayer play];
6、其他屬性、方法
.currentTime 實時時間
.duration 持續(xù)時間
.numberOfLoops 循環(huán)次數(shù)
-pause 暫停
-stop 停止
7、停止后執(zhí)行的方法
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {}
二、AVPlayer的使用,可播放本地和網(wǎng)絡(luò)音視頻
1、實例化播放器對象,并賦予路徑
_avPlayer = [[AVPlayer alloc] initWithURL:[NSURL URLWithString:@"http://mp3.qqmusic.cc/yq/5023716.mp3"]];
2、開始播放
[_avPlayer play];
三、播放系統(tǒng)聲音
添加全局變量
SystemSoundIDsoundID;//系統(tǒng)聲音標識符
1、獲取本地聲音文件
NSString *sysPath = [[NSBundle mainBundle]pathForResource:@"44th Street Medium.caf" ofType:nil];
2、將路徑轉(zhuǎn)換成URL
NSURL *sysUrl=[NSURL fileURLWithPath:sysPath];
3、注冊聲音成為系統(tǒng)聲音
__bridge橋接? 讓ARC管理CF框架的內(nèi)存釋放
CFArrayRef -->NSArray
CFStringRef -->NSString
AudioServicesCreateSystemSoundID((__bridge CFURLRef)sysUrl, &soundID);
4、播放系統(tǒng)聲音
AudioServicesPlaySystemSound(soundID);
5、播放震動只能真機演示
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
6、暫停系統(tǒng)聲音? 還可以繼續(xù)播放
AudioServicesDisposeSystemSoundID(soundID);
7、完全停止系統(tǒng)聲音
AudioServicesRemoveSystemSoundCompletion(soundID);
}
==================================================================================================================================================
{
??、多線程
注意:
1.一個應(yīng)用可以有多個進程,一個進程包含多個線程
2.同步、異步、阻塞、非阻塞、死鎖、互斥鎖、信息量
3.并發(fā):兩個人拿著一把鏟挖一個坑
并行:兩個人拿著兩把鏟挖一個坑
并行一定并發(fā),并發(fā)不一定并行
4.一個程序有且只有一個主線程, 串行的,與應(yīng)用程序綁定
5.任何能夠阻塞主線程的任務(wù)都不因該放在主線程
6.cancel只有一個作用:把某個開啟的線程標志為取消狀態(tài)
如果一個線程剛開啟就標志位取消狀態(tài),那么這個線程會被殺死,節(jié)約系統(tǒng)資源
exit退出一個線程
7.一個線程所占內(nèi)存是固定的,主線程1M,多線程512kB,所以不能無限開啟多線程
8、線程池:多線程創(chuàng)建出來后會被放到線程池,需要用時在池中取
9、多線程實現(xiàn)的是提高了資源的使用率
10、主線程:用戶觸摸、滑動事件、UI相關(guān)操作必須放在主線程,只有主線程有直接修改UI的能力
多線程:耗時的操作一定不能放在主線程
不能在子線程中更新UI,因為屬性都是非線程保護的,多個線程可以同時訪問此資源,如果同時更新同一個UI空間,可能會到時花屏
11、線程的狀態(tài):新-可運行=運行-死
12、同步不會開啟新的線程
異步會開啟新的線程
13、
一、NSThread
1.直接使用NSThread創(chuàng)建多線程 + 開啟
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(thread1) object:nil];
[thread1 start];
(常用)2.直接使用類方法創(chuàng)建多線程 不需要開啟(分離線程)
[NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];
3.通過NSObject提供的類目創(chuàng)建多線程序
[self performSelectorInBackground:@selector(test) withObject:nil];
4.創(chuàng)建一個子類繼承雨NSThread,要通過start開啟子類線程來實現(xiàn)多線程,復(fù)寫main方法,是線程的主題方法,不能直接調(diào)用main方法,直接調(diào)用是普通的對象調(diào)用父類實例方法,不是多線程
-currentThread 當前線程
+isMainThread 是否是主線程
+isMultiThread 是否是多線程
+sleepForTimeInterval 睡眠幾秒
+exit 退出線程(應(yīng)該退出已經(jīng)標志為取消狀態(tài)的進程)
+setThreadPriority 設(shè)置線程優(yōu)先級(沒有開啟之前設(shè)置,默認0.5,主線程開啟優(yōu)先級就確定,無法修改)
.name 設(shè)置線程名稱
.executing 是否正在執(zhí)行
.finished 是否已經(jīng)結(jié)束
.cancelled 是否是取消(狀態(tài))
.threadPriority 線程優(yōu)先級(float)
二、線程的狀態(tài) (NSThread一個線程只能開啟一次)
1、創(chuàng)建線程對象 新建狀態(tài)
2、開啟線程 就緒狀態(tài)
3、調(diào)用方法 運行狀態(tài)
4、方法結(jié)束 死亡狀態(tài)
5、在支線程設(shè)置runloop,保證線程不死王
三、線程通信
(重要)1、在支線程中要注意內(nèi)存管理,開啟一個自動釋放池,將帶嗎放到自動釋放池中
2、切換到主線程中,將數(shù)據(jù)傳過去
方法一、
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
方法二、
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
方法三、
[_imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
NSOperation 操作任務(wù),一般情況下使用它的子類
一、NSBlockOperation
1、創(chuàng)建,并在block中定義任務(wù)
NSBlockOperation *_blockOperation = [NSBlockOperation blockOperationWithBlock:^{}];
2、執(zhí)行任務(wù),位置決定了是否是在支線程
[_blockOperation start]
二、NSOperationQueue
1、創(chuàng)建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
2、將任務(wù)添加到隊列中,自動執(zhí)行任務(wù),執(zhí)行的順序跟數(shù)組的次序一致,但只是在并發(fā)數(shù)唯一的情況下
[queue addOperations:@[blockOperation1,blockOperation2,blockOperation3,blockOperation4] waitUntilFinished:YES];
3、設(shè)置任務(wù)的優(yōu)先級,影響的是CPU分配給當前任務(wù)的事件多少(必須在添加到隊列之前設(shè)置,枚舉)
blockOperation1.queuePriority = NSOperationQueuePriorityVeryHigh;
4、設(shè)置最大并發(fā)數(shù)(為1會使線程變成2,為2可看出線程重復(fù)利用)
queue.maxConcurrentOperationCount = 2;
5、隊列中開啟的線程可以重復(fù)使用
(重要)6、依賴關(guān)系 (前依賴后)
[blockOperation4 addDependency:blockOperation2];
三、NSInvocationOperation
1、創(chuàng)建
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(fun)
object:nil];
2、開啟(在當前線程)
3、加在隊列中(多線程)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:invocationOperation];
4、獲取主隊列
5、在主隊列中添加線程,就可以將信息UI傳回主線程(block)
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
四、鎖 互斥鎖、遞歸鎖、分布鎖? 讓一塊內(nèi)存空間在一個時間內(nèi)只能被一個對象修改
加了鎖之后,同時只能有一個線程訪問此資源
如果不加鎖,在延遲的時間里 如果有其他線程訪問此資源就可能出現(xiàn)-到負數(shù)的情況
當?shù)谝粋€線程訪問此資源時,當其他線程訪問此資源時需要等待
(重要)1、創(chuàng)建鎖對象(全局)
_lock = [[NSLock alloc] init];
2、加鎖 保證資源只能被同一個線程修改,一個資源只能加一次鎖,加兩次以上會鎖死
[_lock lock];
3、要鎖的內(nèi)容
4、解鎖
[_lock unlock];
5、類似自動釋放池的鎖
@synchronized(self){? 要鎖的內(nèi)容? }
}
==================================================================================================================================================
{
??、GCD(Grand Central Dispatch) 大型任務(wù)分發(fā)中心
1.優(yōu)點:純C編寫,易用、效率、性能、安全。
2.Dispatch Queue 串行、并行、主隊隊列,所有主隊列的任務(wù)都在主線程。
全局隊列(多線程)、串行隊列(有可能是多線程,取決于它在哪個線程)
3.同步:提交任務(wù)必須等待任務(wù)完成,才可繼續(xù)提交
異步:提交任務(wù)不需要完成,就可以繼續(xù)提交
串行隊列:一個任務(wù)執(zhí)行完,下一個任務(wù)才可以執(zhí)行
并發(fā)隊列:一個任務(wù)沒有執(zhí)行完,也可以執(zhí)行下一個任務(wù)
一、GCD的使用
1.創(chuàng)建串行隊列(單個線程) 參數(shù)1 字符串隊列的名稱(id+項目名+名字)? 參數(shù)2 隊列的類型
dispatch_queue_t queue1 = dispatch_queue_create("queue1", NULL);
dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_SERIAL);
2.創(chuàng)建并發(fā)隊列(多個線程) 第二個參數(shù)只能使用給定的宏
dispatch_queue_t queue3 = dispatch_queue_create("queue3", DISPATCH_QUEUE_CONCURRENT);
3.獲取全局隊列 運行在全局隊列中的任務(wù),必定是在多線程中 特殊的并發(fā)隊列,一般的多線程都使用這個
第一個參數(shù) 全局隊列的優(yōu)先級(高、默認、低、后臺)
第二個參數(shù) 是API留作未來使用,默認0
dispatch_queue_t globaQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
4.獲取主隊列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
二、提交任務(wù)
(重點)1.同步提交 需要等待,提交到哪個線程,就公用哪一個線程
dispatch_sync(serialQueue, ^{ 任務(wù)內(nèi)容 });
2.異步提交 提交到串行隊列:誰先提交誰先執(zhí)行,使用單個線程
提交到并發(fā)隊列:多線程,先提交不一定先執(zhí)行完,提交沒有執(zhí)行完,后面的任務(wù)可以繼續(xù)提交
dispatch_async(concurrentQueue, ^{ 任務(wù)內(nèi)容 });
3.間隔2s之后向主線程提交一個任務(wù)
4.使用GCD創(chuàng)建單例
+ (instancetype)shareInstance {
//把onceToken當做布爾值來用,判斷onceToken是否是yes,如果是就不執(zhí)行,如果不是就執(zhí)行
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init]; });
return instance;
}
5、數(shù)據(jù)返回主線程(更新UI)在GCD中嵌入GCD
三、死鎖? ? 使用同步提交的方式提交到主線程一個任務(wù)
原因:本次任務(wù)還未完成還要給主線程(串行)添加任務(wù),那么本身的任務(wù)永遠完成不了
解決辦法:不要把它放到主線程,放到多線程
建議:不要使用同步提交方式
三、Dispatch Group (重要) 無法取消
1.創(chuàng)建隊列和group對象
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
2.往group添加任務(wù) 參數(shù):group對象 隊列 任務(wù)
dispatch_group_async(group, queue, ^{ });
3.匯總?cè)蝿?wù)一 參數(shù):droup對象 隊列? 不會阻塞主線程 所有任務(wù)完成后調(diào)用
相當于監(jiān)聽,前面任務(wù)完全完成后在執(zhí)行
dispatch_group_notify(group, queue, ^{? });
匯總?cè)蝿?wù)二 參數(shù):參照時間 時間(微秒,秒,納秒)? ? 設(shè)置等待時間? 是在主線程進行,會阻塞當前線程
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
long result = dispatch_group_wait(group, time);
if(result == 0) {所有任務(wù)都已完成} 返回其他數(shù)值,沒有執(zhí)行完,超時
四、NSRunLoop
1.線程的5個狀態(tài):新建、就緒、運行、阻塞、死亡
2.開RunLoop是為了能讓程序處在活躍狀態(tài)
3.開啟一個新的線程,不會把定時器添加到當前RunLoop中
4.開啟新的線程需要手動開啟runloop
5.定時器不精準,很有可能卡死
6.手機屏幕刷新率60次/s,獲取屏幕刷新率對象,模擬器沒有刷新率
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayMethod)];
添加到世界循環(huán)
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
屏幕梅刷新一次就會調(diào)用一次displayMethod,可以設(shè)置一個全局變量value來控制事件
五、Dispatch_once_t 標簽變量
1、創(chuàng)建標簽變量
static dispatch_once_t onceToken;
2、把需要標志的操作放進去,保證只執(zhí)行一次
dispatch_once(&onceToken, ^{
//這里的操作只會執(zhí)行一次
});
3、用法:創(chuàng)建單例(三個方法)
召喚:dispatch_once
六、延時調(diào)用
1、創(chuàng)建延時時間? ? 時間參考點 指定的時間
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC);
2、調(diào)用GCD延時函數(shù)
dispatch_after(time, dispatch_get_global_queue(0, 0), ^{? 要執(zhí)行的操作? });
3、在哪個線程開啟,就在那個線程掛起
[self performSelector:@selector(delayAction) withObject:nil afterDelay:5];
4、取消掛起的方法
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(delayAction)
object:nil];
七、GCD遍歷數(shù)組
1、枚舉器遍歷
[array enumerateObjectsUsingBlock:^(id? _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%ld? %@ ", idx, obj);
}];
2、Dispatch_Apply(多線程遍歷,哪個閑置用哪個,多個線程)
//Dispatch_Apply遍歷
使用GCD實現(xiàn)遍歷 充分利用多線程的性能 必須放到全局隊列中
把循環(huán)的每次迭代提交到queue中執(zhí)行, 將循環(huán)的任務(wù)追加到隊列中 如果是并行隊列
就會開啟多線程 在后臺線程中執(zhí)行
參數(shù)1:數(shù)組的元素個數(shù)
參數(shù)2:指定的隊列
參數(shù)3:表示循環(huán)到第幾次? ?無符號長整形
dispatch_apply(array.count, dispatch_get_global_queue(0, 0), ^(size_t index) {
NSLog(@"%ld? %@", index, array[index]);
});
八、精準定時器
1、主線程中開啟的定時器會阻塞線程,UI界面的操作會影響主線程,導(dǎo)致卡頓現(xiàn)象,定時器不會調(diào)用方法
解決:使用添加到事件循環(huán),comment模式
2、在支線程中開啟+開啟事件循環(huán),防止線程死掉
//定時器二
NSTimer *timer = [NSTimer timerWithTimeInterval:1
target:self
selector:@selector(timerAction:)
userInfo:nil
repeats:YES];
//模式選擇NSRunLoopCommonModes
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
定時器不使用時,應(yīng)該使其失效,并置空
[_timerinvalidate];
_timer=nil;
3、精準定時器 利用頻幕的刷新率 也會阻塞? ? 利用屏幕的刷新率? 60HZ? 每刷新一次調(diào)用一次綁定的方法
frameInterval 每隔多少幀調(diào)用一次
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timerAction:)];
link.frameInterval = 60;
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
==================================================================================================================================================
{
??、網(wǎng)絡(luò)編程
一、http協(xié)議 超文本傳輸協(xié)議
1.請求方式:GET請求、POST請求
2.請求包結(jié)構(gòu):請求頭、請求體(GET只有請求頭)
3.請求頭類似于字典
4.狀態(tài)碼,表示響應(yīng)結(jié)果,4開頭都是服務(wù)器有問題
5.響應(yīng)頭中的Content-Type表示響應(yīng)體中的數(shù)據(jù)類型
6.同步請求:在主線程進行,會導(dǎo)致只線程阻塞
異步請求:多線程進行
UI界面的渲染與刷新在主線程中進行,主線程不流暢會導(dǎo)致UI界面卡頓
7.C\S 客戶端? <- 連接通道 -> B\S 服務(wù)器端
8、服務(wù)器端開發(fā)語言:Java? ?.Net? ?PHP? ?C/C++? ?Ruby? ?Python
9、客戶端與服務(wù)器端的數(shù)據(jù)傳輸,數(shù)據(jù)必須約定使用同一種格式,例如:json、xml <—>二進制
10、HTTP協(xié)議:超文本傳輸協(xié)議、國際通用協(xié)議,瀏覽器和服務(wù)器之間的通信規(guī)則
11、客戶端? ———————請求包——————>? 服務(wù)端
<——————響應(yīng)包——————
12、GET請求:向服務(wù)器索取數(shù)據(jù)(請求頭)
POST請求:向服務(wù)器提交數(shù)據(jù)(請求頭、請求體)
13、請求頭:描述所請求的數(shù)據(jù)
14、響應(yīng)包
響應(yīng)頭:描述我想要的數(shù)據(jù)(返回的)是數(shù)據(jù)樣子
響應(yīng)體:我們所需要的東西
15、豆瓣API 主接口+子接口
16、請求頭拼接參數(shù) 接口?key=value&key=value&key=value
Request Properties 認可的參數(shù)列表
17、URL 資源定位符,接口
18、步驟:(修改plist文件)NSURL-NSURLRequest-NSURLSessionCongiguration(可選)-NSURLSession-NSURLSessionDataTask-執(zhí)行
19、session類型
默認:持久化,基于磁盤緩存
臨時:內(nèi)存中
后臺
20、無名拼接、json拼接
21、data轉(zhuǎn)換成string
二、網(wǎng)絡(luò)組件 NSURLSession <<五步走>>
1.構(gòu)建NSURL實例
NSURL *url = [NSURL URLWithString:@"https://api.douban.com/v2/movie/top250"];
2.構(gòu)建NSURLRequest對象(默認GET請求),設(shè)置請求配置 (url對象,緩存策略,超時時間)
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60];
3.創(chuàng)建網(wǎng)絡(luò)會話,單例對象
NSURLSession *session = [NSURLSession sharedSession];
4.使用會話對象發(fā)送網(wǎng)絡(luò)請求 返回值是會話任務(wù)對象 (服務(wù)器發(fā)給響應(yīng)體的二進制數(shù)據(jù),響應(yīng)頭數(shù)據(jù))(在多線程)
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//? ? 解析二進制數(shù)據(jù)
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:nil];
NSLog(@"%@", dic);? ? ? ?//解析后的數(shù)據(jù)
NSLog(@"%@", response);? //請求頭的數(shù)據(jù)
//NSLog(@"%@", data);? ? //未解析的二進制數(shù)據(jù)
}];
5.執(zhí)行任務(wù)
[task resume];
三、GET請求 (異步發(fā)送的請求,多線程)
1.創(chuàng)建URL對象 帶參數(shù)的GET請求
NSURL *url = [NSURL URLWithString:@"https://api.douban.com/v2/movie/top250"];
2.創(chuàng)建request對象 這個設(shè)置的參數(shù)較少,不好
建議使用它的子類NSMutableURLResquest
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//緩存策略
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
//超時時間
[request setTimeoutInterval:120];
//請求方式(默認是GET請求)
[request setHTTPMethod:@"GET"];
//HTTPBody 請求體
//HTTPHeader 請求頭
3.NSURLSession
NSURLSession *session = [NSURLSession sharedSession];
4.task
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//容錯
if (error == nil) {
//對比NSURLResponse和NSHTTPURLResponse(狀態(tài)碼、響應(yīng)頭)
NSLog(@"response = %@", response);
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@"httpRespomse = %ld", (long)httpResponse.statusCode); //狀態(tài)碼
NSLog(@"httpRespomse = %@", httpResponse.allHeaderFields); //響應(yīng)頭
//error容錯判斷 和 NSRerror
NSError *jsonError = nil;
[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&jsonError];
if (jsonError) {
NSLog(@"jsonError = %@", jsonError);
}
}
}];
//5.設(shè)置plist文件 App Transport
[task resume];
//6.(警告)刷新UI
dispatch_sync(dispatch_get_main_queue(), ^{
//UI部分就寫在這
});
四、POST請求
微博API-開放平臺-API文檔-接口測試
1.url 網(wǎng)址先測試,再使用 參數(shù)拼接順序不影響結(jié)果,
NSURL *url = [NSURL URLWithString:@"https://api.weibo.com/2/statuses/update.json"];
2.request 使用子類的
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
超時時間
[request setTimeoutInterval:120];
請求方法類型
[request setHTTPMethod:@"POST"];
(重要)請求體,接口是已經(jīng)登錄的微博的接口(倆個參數(shù)是必須的)
NSString *bodyString = @"access_token=2.00f3FX5GLS4fbC3e06717e8d09Abdi&status=有一種孤獨,叫我還未成年";
轉(zhuǎn)換成二進制數(shù)據(jù)
NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:bodyData];
3.session 單例
NSURLSession *session = [NSURLSession sharedSession];
4.task 發(fā)送請求
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data,NSURLResponse * _Nullable response, NSError * _Nullable error) {
響應(yīng)頭
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@"%ld", httpResponse.statusCode);
}];
5.執(zhí)行任務(wù)
[task resume];
四、懶加載 用到的時候才加載
1.不生成get、set方法 @dynamic
生成get、set方法 @synthesize
2.實際就是一個get方法
- (NSArray *)paths {
if (paths == nil) {
paths = [NSArray array];
}
return paths;
}
五、NSURLSession指的是一個網(wǎng)絡(luò)會話,一個會話可以發(fā)起多個任務(wù),一個任務(wù)對應(yīng)一次網(wǎng)絡(luò)請求
1.Session類型:默認、臨時、后臺(退出后臺仍然能夠下載,下載完后重新打開程序)
六、NSURLSessionConfigration用于配置Session對象
1.url
NSURL *URL = [NSURL URLWithString:@"https://api.douban.com/v2/movie/coming_soon"];
2.urlResquest 如果POST請求,需要創(chuàng)建Resquest對象,設(shè)置請求體
3.創(chuàng)建configuration(默認、臨時、后臺)
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
超時時間(默認60s)
configuration.timeoutIntervalForRequest = 120;
設(shè)置是否可以使用蜂窩數(shù)據(jù)
configuration.allowsCellularAccess = YES;
4.Session (不能使用單例,應(yīng)該使用代理方式創(chuàng)建,創(chuàng)建在哪個線程)
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];? ?//創(chuàng)建在主線程
5.發(fā)送請求,返回task
NSURLSessionDataTask *task = [session dataTaskWithURL:URL];
6.執(zhí)行請求
[task resume];
7.實現(xiàn)協(xié)議方法
(1)、接收到響應(yīng)頭會調(diào)用(多次),需要調(diào)用block,傳遞allow參數(shù)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@"response.statuscode = %ld", httpResponse.statusCode);? ?//打印狀態(tài)碼
}
(2)、數(shù)據(jù)請求完畢調(diào)用的協(xié)議方法(數(shù)據(jù)反回調(diào)用的方法)上面的方法復(fù)寫后,此方法不會被調(diào)用,要想調(diào)用這個方法,那么必須在上個方法調(diào)用block(重要)。
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
id result = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:nil];
NSLog(@"%@",result);
}
(3)、數(shù)據(jù)傳輸完成之后調(diào)用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask {
//查看是否是在主線程
NSLog(@"%d", [[NSThread currentThread] isMainThread]);
}
(4)、請求完成后,不管失敗,還是成功都會調(diào)用的方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
//? ? NSLog(@"%@", error);
}
七、上傳數(shù)據(jù)
1、URL
NSURL *url = [NSURL URLWithString:@"https://upload.api.weibo.com/2/statuses/upload.json"];
2、設(shè)置請求方式:POST
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
3、設(shè)置請求頭
NSString *headerString = [NSString stringWithFormat:@"multipart/form-data; charset=utf-8;boundary=%@", boundary];
[request setValue:headerString forHTTPHeaderField:@"Content-Type"];
4、構(gòu)造請求體:(1)、access_token? ?(2)、status? (3)、pic
百分號%%? 雙引號\” \”
NSMutableString *mBodyString = [NSMutableString string];
[mBodyString appendFormat:@"--%@\r\n", boundary];
[mBodyString appendFormat:@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n"];
[mBodyString appendFormat:@"2.00bEgIqC0ll_TLe543cd66dc07uEQR"];
[mBodyString appendFormat:@"--%@\r\n", boundary];
[mBodyString appendFormat:@"Content-disposition: form-data; name=\"status\"\r\n\r\n"];
[mBodyString appendFormat:@"撒盧卡\r\n"];
[mBodyString appendFormat:@"--%@\r\n", boundary];
//拼接圖片數(shù)據(jù)
[mBodyString appendFormat:@"Content-disposition: form-data; name=\"pic\"; filename=\"這個名字是隨意的\"\r\n"];
[mBodyString appendFormat:@"Content-Type: application/octet-stream\r\n\r\n"];
NSData *data = [mBodyString dataUsingEncoding:NSUTF8StringEncoding];
NSData *imageData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"timg.jpg" ofType:nil]];
NSMutableData *mdata = [NSMutableData data];
[mdata appendData:data];
[mdata appendData:imageData];
NSString *endString = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary];
[mdata appendData:[endString dataUsingEncoding:NSUTF8StringEncoding]];
//請求體
request.HTTPBody = mdata;
5、創(chuàng)建會話
NSURLSession *session = [NSURLSession sharedSession];
6、根據(jù)會話創(chuàng)建任務(wù),上傳數(shù)據(jù)
NSURLSessionDataTask *task = [session uploadTaskWithRequest:request fromData:mdata completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
NSLog(@"success");
};
}];
7、執(zhí)行任務(wù)
[task resume];
八、下載數(shù)據(jù)(不能實時監(jiān)聽)
1、URL
2、session
3、創(chuàng)建網(wǎng)絡(luò)任務(wù)(收到的數(shù)據(jù):文件的沙盒路徑、請求頭、error)
先是存在tmp臨時文件夾,如果不將它存到自己的文件夾,出了block之后就會被刪除
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//blcok 下載完畢之后在調(diào)用,不能實時監(jiān)聽
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/后會無期.mp3"];
NSLog(@"%@",filePath);
NSURL *url = [NSURL fileURLWithPath:filePath];
//location文件的位置,下載后無法儲存文件,(臨時的文件,)block代碼塊執(zhí)行完畢,
//文件會被刪除
BOOL isScuess= [[NSFileManager defaultManager]copyItemAtURL:location toURL:url error:nil];
if (isScuess) {
NSLog(@"下載成功");
}
}];
4、拷貝一份下載的數(shù)據(jù)
九、下載任務(wù)(實時監(jiān)聽)
1、URL
NSURL *url = [NSURL URLWithString:@"http://www.itinge.com/music/3/9158.mp3"];
2、創(chuàng)建一個會話配置對象configuration(默認、支持后臺、)
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
3、利用configuration創(chuàng)建session,協(xié)議
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
4、創(chuàng)建下載任務(wù)(注意是下載任務(wù))
NSURLSessionDownloadTask *dataTask = [session downloadTaskWithURL:url];
5、實現(xiàn)代理方法
(1)、正在下載(調(diào)用多次)
網(wǎng)絡(luò)任務(wù)
網(wǎng)絡(luò)會話
當前下載下來的數(shù)據(jù)
當前下載下載的總數(shù)據(jù)
文件總大小
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
self.processView.progress = (double)totalBytesWritten/totalBytesExpectedToWrite;
}
(2)、已經(jīng)完成下載
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location {
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/后會無期.mp3"];
NSLog(@"%@",filePath);
NSURL *url = [NSURL fileURLWithPath:filePath];
//location文件的位置,下載后無法儲存文件,(臨時的文件,)block代碼塊執(zhí)行完畢,
//文件會被刪除
BOOL isScuess= [[NSFileManager defaultManager]copyItemAtURL:location toURL:url error:nil];
if (isScuess) {
NSLog(@"下載成功");
}
}
十、斷點續(xù)傳
1、取消任務(wù),記錄下載量
[_task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
//記錄暫停時的下載位置,指示標志一下,并不是真是下載量
_data = resumeData;
}];
2、根據(jù)下載量構(gòu)造全新任務(wù)
//根據(jù)斷點重新構(gòu)造任務(wù)
_task = [_session downloadTaskWithResumeData:_data];
[_task resume];
十一、后臺下載
1、將configuration修改為后臺下載
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"CYC666"];
十二、封裝網(wǎng)絡(luò)請求
1、自定義的類方法
+ (void)requestWithUrl:(NSString *)url httpMethod:(NSString *)method pamaleter:(NSMutableDictionary *)pamaleter; {
//1、構(gòu)建URL
NSURL *requestUrl = [NSURL URLWithString:url];
//2、構(gòu)建請求request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestUrl];
//3、設(shè)置請求方式
request.HTTPMethod = method;
//4、拼接參數(shù)
NSMutableString *mString = [NSMutableString string];
NSArray *keys = [pamaleter allKeys];
for (int i = 0; i < pamaleter.count; i++) {
NSString *key = keys[i];
NSString *value = pamaleter[key];
[mString appendFormat:@"%@=%@", key,value];
//最后一個參數(shù)不需要拼接&
if (i <= pamaleter.count-1) {
[mString appendFormat:@"&"];
}
}
if ([method isEqualToString:@"GET"]) {//GET請求
//判斷URL后面是否拼接有參數(shù),有則拼&,無則拼?
NSString *seper = requestUrl.query ? @"&" : @"?";
url = [NSString stringWithFormat:@"%@%@%@", url, seper, mString];
//重新設(shè)置一下url(因為url重新拼接了)
request.URL = [NSURL URLWithString:url];
} else {
//設(shè)置請求體
request.HTTPBody = [mString dataUsingEncoding:NSUTF8StringEncoding];
}
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
NSLog(@"success!");
};
}];
[task resume];
}
2、調(diào)用
//拼接參數(shù)
NSDictionary *dic = @{
@"access_token":@"2.00BSUoQClB87iBba5e1aa3331qYmpC",
@"status":@"你的嗓音就是世界的禍害"
};
[CYCNetService requestWithUrl:@"https://api.weibo.com/2/statuses/update.json"
httpMethod:@"POST"
pamaleter:[dic mutableCopy]];
十三、AFNetworking 從github獲取第三方框架
1、簡單的GET請求
(1)、URL
NSString *urlStr = @"http://piao.163.com/m/cinema/list.html?apiVer=6&city=110000";
(2)、manager對象 用來管理網(wǎng)絡(luò)請求
AFHTTPSessionManager *manager=[AFHTTPSessionManager manager];
(3)、發(fā)送GET請求(主線程!!!!!)
[manager GET:urlStr parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id? _Nonnull responseObject) {
//默認解析json類型
NSLog(@"responseObject = %@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error = %@",error);
}];
2、簡單的POST請求
(1)、URL
(2)、manager對象
AFHTTPSessionManager *manager=[AFHTTPSessionManager manager];
(3)、拼接參數(shù)
NSDictionary *dic=@{@"cinema_id":@1533};
(4)、默認是以拼接類型上傳給服務(wù)器? 默認解析為json類型
A、告訴服務(wù)器以拼接類型來解析客戶端傳給服務(wù)器的數(shù)據(jù),拼接類型
AFHTTPRequestSerializer *jointSerializer=[AFHTTPRequestSerializer serializer];
manager.requestSerializer=jointSerializer;
B、告訴服務(wù)器以json類型來解析客戶端傳給服務(wù)器的數(shù)據(jù)
json? 字典類型{"cinema_id" : 1533}? ? 數(shù)組類型[]
AFJSONRequestSerializer *jsonSerializer=[AFJSONRequestSerializer serializer];
manager.requestSerializer=jsonSerializer;
(5)、服務(wù)器返回給客戶端時,你需要解析的數(shù)據(jù)類型
A、服務(wù)器返回的數(shù)據(jù)不解析
AFHTTPResponseSerializer *responserSer=[AFHTTPResponseSerializer serializer];
manager.responseSerializer=responserSer;
B、可以解析為json類型
AFJSONResponseSerializer *jsonResponserSer=[AFJSONResponseSerializer serializer];
manager.responseSerializer=jsonResponserSer;
C、如果可以解析為XML類型才可以設(shè)置? ?如果不支持解析為xml類型那么默認不解析
AFXMLParserResponseSerializer *xmlPar=[AFXMLParserResponseSerializer serializer];
manager.responseSerializer=xmlPar;
D、直接解析為一個UIImage對象
AFImageResponseSerializer
(6)、發(fā)送請求
[manager POST:str parameters:dic success:^(NSURLSessionDataTask * _Nonnull task, id? _Nonnull responseObject) {
//responseObject 最終返回的響應(yīng)體數(shù)據(jù)
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error = %@",error);
}];
3、發(fā)送圖片微博
(1)、manager對象
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
(2)、拼參數(shù)
NSDictionary *parameters = @{@"access_token" : @"2.00f3FX5GLS4fbC3e06717e8d09Abdi",@"status" : @"天氣很涼爽"};
(3)、發(fā)送POST請求
[manager POST:@"https://upload.api.weibo.com/2/statuses/upload.json" parameters:parameters constructingBodyWithBlock:^(id _Nonnull formData) {
A、獲取圖片數(shù)據(jù)
NSData *imageData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"test.jpg" ofType:nil]];
B、上傳的圖片數(shù)據(jù)拼接在formData中
[formData appendPartWithFileData:imageData name:@"pic" fileName:@"file" mimeType:@"image/jpeg"];
}
success:^(NSURLSessionDataTask *_Nonnull task,id _Nonnull responseObject) {
NSLog(@"上傳成功");
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
NSLog(@“失敗”);
}
];
4、下載任務(wù)
(1)、manager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
(2)、URL
NSURL *url = [NSURL URLWithString:@"http://mp3.qqmusic.cc/yq/5023716.mp3"];
(3)、構(gòu)建request
NSURLRequest *request = [NSURLRequest requestWithURL:url];
(4)、下載請求
NSProgress *progress = nil; //把NSProgress對象存在progress中
NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:&progress
destination:^NSURL *_Nonnull(NSURL *_Nonnull targetPath, NSURLResponse *_Nonnull response) {
A、targetPath是一個臨時保存在本地磁盤的位置
NSLog(@"targetPath = %@", targetPath);
B、文件在沙盒中保存的位置
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/wake(live).mp3"];
C、block有返回值? 文件需要保存的位置
return [NSURL fileURLWithPath:path];
}
completionHandler:^(NSURLResponse *_Nonnull response, NSURL *_Nullable filePath, NSError *_Nullable error) {
NSLog(@"filePath = %@", filePath);
}
];
(5)、執(zhí)行任務(wù)
[task resume];
十四、XML 一種存儲數(shù)據(jù)的格式
一、文檔聲明、元素節(jié)點、屬性
二、解析方式:DOM、SAX(一邊讀取一邊解析)
三、第三方框架:NSXMLParser(最慢)、libxml2、TBXML(最快,輕量)、、、KissXML
四、拼接XML
1、添加編譯文件libxml2.2.tbd
build phases -> link binary with libraries + libxml2.2.tbd
2、添加KissXML第三方框架
3、導(dǎo)入頭文件
#import "DDXML.h"
4、添加路徑
header search paths -> debug + any architecture|any SDK + user/include/libxml2
五、解析XML
1、DOM解析方式(主流)、SAX解析方式(實時解析,適合大數(shù)據(jù))
2、讀取整個xml文檔
3、獲取子節(jié)點
4、for-in遍歷獲取節(jié)點值
定點查詢
未知查詢
分支查詢(下標從1開始)
六、NSURLConnection
一、同步
//1、URL
NSURL *url = [NSURL URLWithString:@"http://api.douban.com/v2/movie/top250?count=30"];
//2、請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3、響應(yīng)頭
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//4、解析數(shù)據(jù)
id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@", result);
二、異步
NSURL *url = [NSURL URLWithString:@"http://api.douban.com/v2/movie/top250?count=30"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSLog(@"%@", [NSThread currentThread]);
id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@", result);
}];
七、網(wǎng)絡(luò)狀態(tài)監(jiān)測
1、在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 監(jiān)聽
2、添加AFNetworking框架,導(dǎo)入頭文件
3、創(chuàng)建全局manager
4、開始監(jiān)聽
5、狀態(tài)檢測block,每當狀態(tài)改變就會調(diào)用block
}
=================================================================================================================================================
{
??、繪圖與文本
1.Quartz 2D API,基于路徑的繪圖、透明度、陰影、顏色管理、反鋸齒、PDF
2.Core Graphics框架,Quartz 2D引擎。
3.Quartz 2D與分辨率和設(shè)備無關(guān),無需考慮最終繪制目標的設(shè)備
4.Core Garlic框架是基于C的API
5.UIKit依賴于Core Graphics,當引入UIKit時,CG框架會被自動引用
6.UIKit內(nèi)部封裝了CG的一些API
7.Graphics Context相當于畫布,有很多類型
8.Quartz的所有對象都華畫在Graphics Context中
9.定義UIView,實現(xiàn)drawRect方法,如果復(fù)寫了又不實現(xiàn)任何功能,做動畫會極大地影響性能
10.調(diào)用自定義的drawRect后,視圖對象自動配置繪圖環(huán)境以便能立即繪圖操作
11.通過UIGraphicsGetCurrentContext()方法獲取當前的Graphics Context
12.Quartz 默認原點在左下角
13.只能在drawRect中獲取CGContextRef進行繪圖,在其他方法獲取的CGContextRef不能用于繪圖.
如果一定要在其他方法中使用CGContextRef繪圖,那必須要在drawRect中調(diào)用方法,并將CGContextRef傳遞過去
14.使用含有creat、copy函數(shù)創(chuàng)建對象,使用完后必須釋放,否則將導(dǎo)致內(nèi)存泄漏
15.路徑屬于繪圖信息,。。。屬于繪圖狀態(tài)
一、Quartz 2D
1.創(chuàng)建子類化UIView的類化
2.在子類中復(fù)寫drawRect方法
3.獲取系統(tǒng)已經(jīng)創(chuàng)建好的Context(這個東西系統(tǒng)會自動幫我們創(chuàng)建)
CGContextRef contextRef = UIGraphicsGetCurrentContext();
4.創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPath];
5.添加到上下文
CGContextAddPath(contextRef, path.CGPath);
6.繪制路徑
CGContextStrokePath(contextRef);
7、設(shè)置線條終點形狀
CGContextSetLineCap(ref, kCGLineCapRound);
8、設(shè)置虛線
float? lengths[] = {15,10};? //15表示實線長度,10表示虛線長度
CGContextSetLineDash(context, 0, lengths,2);? ? ?//上下文、(寫0就好)、數(shù)組、數(shù)組長度
9、設(shè)置透明度
CGContextSetAlpha(ref, .5);
10、修改畫布坐標系
CGContextRotateCTM(contextRef, M_PI);? ?//旋轉(zhuǎn)
CGContextTranslateCTM(contextRef, 0, -rect.size.height);? ? //平移
CGContextScaleCTM(contextRef, -1, 1);? ?//縮放
11、設(shè)置陰影
CGContextSetShadow(ref, CGSizeMake(10, 20), 5);? ? //陰影當偏移、羽化大小,這個方法默認黑色陰影
CGContextSetShadowWithColor(ref, CGSizeMake(10, 20), 5, [UIColor yellowColor].CGColor);? ? //可以自定義陰影顏色
12、設(shè)置線寬
CGContextSetLineWidth(ref, 5);
13、設(shè)置線條顏色
[[UIColor orangeColor] setStroke];
14、設(shè)置填充顏色
[[UIColor yellowColor] setFill];
線條的類型
path.lineCapStyle=kCGLineCapRound;
15、(重要)當需要刷新繪制的圖形時,相當于在當前視圖添加了一個重繪標記,等到下一次屏幕刷新時,系統(tǒng)會創(chuàng)建好默認的上下文,然后調(diào)用drawRect
[self setNeedsDisplay];
二、水印
1.開啟位圖上下文,他就是一塊內(nèi)存區(qū)域
UIImage *image = [UIImage imageNamed:@"WeChatLaunch@3x.png"];
UIGraphicsBeginImageContext(image.size);
2.將圖片添加到上下文
[image drawAtPoint:CGPointZero];
3.繪制文字水印
NSString *string = @"CYC666";
NSDictionary *dic = @{
NSFontAttributeName : [UIFont systemFontOfSize:30],
NSForegroundColorAttributeName : [UIColor redColor]
};
[string drawAtPoint:CGPointMake(image.size.width-200, image.size.height-50) withAttributes:dic];
4.從當前上下文中獲取已經(jīng)添加水印的圖片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
(重要)5.關(guān)閉位圖上下文
UIGraphicsEndImageContext();
//將圖片存入相冊
UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
三、圖形的繪制
// 回執(zhí)的時候必須使用這種方式,不能設(shè)置填充顏色
CGContextDrawPath(contextRef, kCGPathFillStroke);
kCGPathFill, ? ? // 填充,沒有線條
kCGPathEOFill, ? ? // 只有線條
kCGPathStroke,
kCGPathFillStroke,// 線條?填充
kCGPathEOFillStroke
//繪制三角形
//1.獲取圖形上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//2.創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPath];
//3.設(shè)置路徑
[path moveToPoint:CGPointMake(30, 50)];
[path addLineToPoint:CGPointMake(200, 50)];
[path addLineToPoint:CGPointMake(200, 150)];
//將路徑首尾連接
[path closePath];
//將路徑添加到上下文
CGContextAddPath(contextRef, path.CGPath);
//填充顏色(黃色)
CGContextSetRGBFillColor(contextRef, 1, 1, 0, 1);? ? 或? ? [[UIColor blackColor] setFill];
//線寬
CGContextSetLineWidth(contextRef, 1); 或 path.lineWidth
//路徑顏色
[[UIColor orangeColor] setStroke];
//4.繪制路徑
CGContextDrawPath(contextRef, kCGPathFillStroke);
//繪制圓形
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//center 中心點
//radius :半徑
//startAngle 起始的角度
//endAngle 結(jié)束角度
//clockwise 是否順時針
CGPoint center = CGPointMake(150, 300);
float radius = 100;
float startAngle = 0;
float endAngle = M_PI_2;
//創(chuàng)建圓形路徑
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center
radius:radius
startAngle:startAngle
endAngle:endAngle
clockwise:YES];
//連接一條線到圓心,在結(jié)束角度添加
[path addLineToPoint:center];
//閉合路徑,將路徑收尾相連
[path closePath];
//將圖路徑添加到上下文
CGContextAddPath(contextRef, path.CGPath);
CGContextStrokePath(contextRef);
//繪制橢圓
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//創(chuàng)建路徑,oval---橢圓
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(40, 100, 300, 400)];
CGContextAddPath(contextRef, path.CGPath);
//描邊路徑
[path fill];
//畫矩形
CGContextAddRect(ref, CGRectMake(10, 10, 150, 150));
四、圖形上下文棧
1、在改變上下文時,保存一份上下文(保存到棧)
CGContextSaveGState(contextRef);
2、繪圖,但是改變不了棧中的上下文狀態(tài)
3、取出棧中的上下文(繪圖狀態(tài)沒有改變)
CGContextRestoreGState(contextRef);
五、矩陣操作
1.獲取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//修改坐標系
CGContextRotateCTM(contextRef, M_PI);? ?//旋轉(zhuǎn)
CGContextTranslateCTM(contextRef, 0, -rect.size.height);? ? //平移
CGContextScaleCTM(contextRef, -1, 1);? ?//縮放
2.繪制圖片
CGContextDrawImage(contextRef, CGRectMake(0, 0, 100, 100), image.CGImage);//沒有經(jīng)過修改的坐標系是倒置的
六、圖片剪切
1.開啟位圖上下文
UIGraphicsBeginImageContext(image.size);
2.設(shè)置剪裁路徑
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
3.將路徑設(shè)置為剪裁路徑
[path addClip];
4.將圖片描繪在上下文
[image drawAtPoint:CGPointZero];
5.從位圖上下文取出圖片,圖片已經(jīng)剪裁好
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
}
==================================================================================================================================================
、正則表達式
一、基本語法
1.0\d{2}-\d{8}。這里\d后面的{2}({8})的意思是前面\d必須連續(xù)重復(fù)匹配2次(8次)。
2.\b代表著單詞的開頭或結(jié)尾,也就是單詞的分界處。
3.\d是個新的元字符,匹配一位數(shù)字(0,或1,或2,或……)
4.匹配沒有預(yù)定義元字符的字符集合,[.?!]匹配標點符號(.或?或!)。
5.\W? ? ? ? 匹配任意不是字母,數(shù)字,下劃線,漢字的字符
\S? ? ? ? 匹配任意不是空白符的字符
\D? ? ? ? 匹配任意非數(shù)字的字符
\B? ? ? ? 匹配不是單詞開頭或結(jié)束的位置
[^x]? ? ? ? 匹配除了x以外的任意字符
[^aeiou]? ? 匹配除了aeiou這幾個字母以外的任意字符
[a-zA-Z]? ? 表示小寫字母或大寫字母
*? ? ? ? 重復(fù)零次或更多次
+? ? ? ? 重復(fù)一次或更多次
?? ? ? ? 重復(fù)零次或一次
{n}? ? ? ? 重復(fù)n次
{n,}? ? ? ? 重復(fù)n次或更多次
{n,m}? ? ? ? 重復(fù)n到m次
.? ? ? ? 匹配除換行符以外的任意字符
\w? ? ? ? 匹配字母或數(shù)字或下劃線或漢字
\s? ? ? ? 匹配任意的空白符
\d? ? ? ? 匹配數(shù)字
\b? ? ? ? 匹配單詞的開始或結(jié)束
^? ? ? ? 匹配字符串的開始
$? ? ? ? 匹配字符串的結(jié)束
*?? ? ? ? 重復(fù)任意次,但盡可能少重復(fù)
+?? ? ? ? 重復(fù)1次或更多次,但盡可能少重復(fù)
??? ? ? ? 重復(fù)0次或1次,但盡可能少重復(fù)
{n,m}?? ? 重復(fù)n到m次,但盡可能少重復(fù)
{n,}?? ? ? ? 重復(fù)n次以上,但盡可能少重復(fù)
二、在Xcode中的使用
1、導(dǎo)入第三方框架
RegexKitLite-master
2、添加庫文件
libicucore.tbd
3、將libicucore.tbd的編譯環(huán)境改成ARC
-fno-objc-arc
4、導(dǎo)入頭文件
#import "RegexKitLite.h"
5、具體步驟
(1)、定義正則表達式
NSString *regex = @"\\d{3,4}-\\d{7,8}";? ? ?//? ?\\d{3,4}匹配3~4個數(shù)字
(2)、使用正則表達式對字符串進行篩選,篩選結(jié)果存入數(shù)組中
NSArray *result = [text1 componentsMatchedByRegex:regex];
三、經(jīng)典用法
1、檢測微博用戶
NSString *regex = @"@[\\w-]{2,30}";
2、檢測QQ
NSString *regex4 =@"^\\d{6,11}$";
3、檢測話題
NSString *regex = @"#[^#]+#";
4、檢測超鏈接
NSString *regex = @"http(s)?://([a-z0-9A-Z._-]+(/)?)*";
5、組合使用
NSString *regex = [NSString stringWithFormat:@"@[\\w-]{2,30}|#[^#]+#|http(s)?://([a-z0-9A-Z._-]+(/)?)*"];
}
==================================================================================================================================================
{
9、沙盒路徑(SandBox)
一、沙盒里的文件夾包括:
1、Documents 用于存儲用戶數(shù)據(jù),iTunes備份和恢復(fù)的時候會包括此目錄,所以,蘋果建議將程序中建立的或在程序中瀏覽到的文件數(shù)據(jù)保存在該目錄下。
2、Library 包含兩個子目錄:Caches 和 Preferences。
Caches用來存放用戶需要換成的文件。
Preferences是APP的偏好設(shè)置,可以通過NSUserDefaults來讀取和設(shè)置。
3.tmp 用于存放臨時文件,這個可以放一些當APP退出后不再需要的文件。
二、沙盒路徑的獲取
1.獲取沙盒根目錄
NSString *directory = NSHomeDirectory();
2.獲取documents目錄
第一個參數(shù)是說明獲取Doucments文件夾目錄,第二個參數(shù)說明是在當前應(yīng)用沙盒中獲取。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
類似的還有? ? ?NSDocumentDirectory
NSLibraryDirectory
NSCachesDirectory
3.獲取tmp路徑
NSString *tmp = NSTemporaryDirectory();
三、NSFileManager文件操作
NSFileManager是一個單列類,也是一個文件管理器。可以通過NSFileManager創(chuàng)建文件夾、創(chuàng)建文件、寫文件、讀文件內(nèi)容等等基本功能。
1、創(chuàng)建文件夾
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *newPath = [documentsPath stringByAppendingString:@"/new"];
BOOL isSuccess = [fileManager createDirectoryAtPath:newPath
withIntermediateDirectories:YES
attributes:nil
error:nil];
2、創(chuàng)建文件
NSString *iOStext = [documentsPath stringByAppendingString:@"/iOS.txt"];
BOOL isSuccess2 = [fileMafnager createFileAtPath:iOStext
contents:nil
attributes:nil];
3、寫文件
NSString *string = @"CYC要666啦,什么梅你在哪";
BOOL isSuccess3 = [string writeToFile:iOStext
atomically:YES
encoding:NSUTF8StringEncoding
error:nil];
4.讀文件
NSString *readString = [NSString stringWithContentsOfFile:iOStext
encoding:NSUTF8StringEncoding
error:nil];
5、判斷文件是否存在
BOOL isSuccess4 = [fileManager fileExistsAtPath:iOStext];
6.計算文件大小(每個漢字、字母、符號為兩個字節(jié),最后加\0結(jié)束符,一個字節(jié))
unsigned long long fileSize = [[fileManager attributesOfItemAtPath:iOStext error:nil] fileSize];
NSLog(@"fileSize = %lld", fileSize);
7. 計算整個文件夾中所有文件大小
unsigned long long folderSize = [[fileManager attributesOfItemAtPath:documentsPath error:nil] fileSize];
8.移動文件(相當于重命名咯)
NSString *moveToPath = [documentsPath stringByAppendingString:@"/new/iOS.txt"];
BOOL isSuccess6 = [fileManager moveItemAtPath:iOStext
toPath:moveToPath
error:nil];
if (isSuccess6) {
NSLog(@"文件移動成功");
} else {
NSLog(@"文件移動不成功");
}
9.將圖片保存在沙盒路徑中
UIImage *image = [UIImage imageNamed:@"Ahome_tab_icon_3@2x.png.jpg"];
NSData *data = UIImagePNGRepresentation(image);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *patha = [paths objectAtIndex:0];
NSString *imagePath = [patha stringByAppendingString:@"Ahome_tab_icon_3@2x.png.jpg"];
[data writeToFile:imagePath atomically:NO];
四、NSUserDefaults 系統(tǒng)提供的plist數(shù)據(jù)持久化單例類,將存儲在NSuserdefaults中的數(shù)據(jù)寫入了一個以Bundle Identifier命名的plist中。
(注意:需要使用自己的加密算法進行加密,在進行數(shù)據(jù)存儲。)
1、添加數(shù)據(jù)
[[NSUserDefaults standardUserDefaults] setObject:authData forKey:@"SinaWeiboAuthData"];
2、刪數(shù)據(jù)
[[NSUserDefaults standardUserDefaults]removeObjectForKey:@"userpwd"];
五、藍色文件夾與黃色文件夾
1、藍色文件夾存在bundle路徑下,不能通過文件名直接獲取文件,需要拼合路徑
[NSBundle mainBundle].resourcePath //一級路徑
[[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:themePath] //二級路徑
. . .//依次拼接路徑
2、獲取文件
//plist文件
NSString *configPath = [[self themePath] stringByAppendingPathComponent:@"config.plist"];
_colorDic = [NSDictionary dictionaryWithContentsOfFile:configPath];
//獲取image
NSString *filePath = [[self themePath] stringByAppendingPathComponent:imageName];
UIimage *image = [UIImage imageWithContentsOfFile:filePath];
3、紅色文件夾的讀取方式
//讀取plist文件
NSArray *facePlistArr = [NSArray arrayWithContentsOfFile: [[NSBundle mainBundle]pathForResource:@"emoticons.plist" ofType:nil]];
}
==================================================================================================================================================
{
10、CALayer? 負責顯示,view接收事件
一、屬性clipsToBounds
1、圓角
view.layer.cornerRadius = 100;
2、邊框?qū)挾龋吙蝾伾?/p>
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 5;
3、陰影,陰影偏移大小,陰影半徑(羽化)(注意:需要設(shè)置陰影不透明度)
view.layer.shadowOffset = CGSizeMake(-40, 60);
view.layer.shadowColor = [UIColor lightGrayColor].CGColor;
view.layer.shadowRadius = 5;
view.layer.shadowOpacity = .7;
(重點)4、imageView設(shè)置允許圓角裁剪YES,但是設(shè)置了之后就不能設(shè)置陰影了
imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 50;
二、獨立
1、創(chuàng)建
CALayer *layer = [CALayer layer];
(重點)2、設(shè)置frame
ayer.frame = CGRectMake(150, 40, 100, 100);
layer.bounds = CGRectMake(0, 0, 100, 100);? //前倆個數(shù)值是中心點
layer.position = CGPointMake(150, 100);
設(shè)置錨點 注意:(0,0) , (0,1) , (0.5,0.5)... ? ? 參考:http://www.cnblogs.com/acBool/p/5071397.html
layer.anchorPoint = CGPointMake(0,0);
3、設(shè)置背景顏色
4、添加到view.layer
[self.view.layer addSublayer:layer];
三、layer的動畫 (加make的只實現(xiàn)一次效果,其實就是在原始位置進行動作 )
1、平移
layer.transform = CATransform3DMakeTranslation(0, 100, 0);
2、縮放
layer.transform = CATransform3DMakeScale(.5, .5, 1);
3、旋轉(zhuǎn)(旋轉(zhuǎn)的軸置為1)
layer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
4、使用lvc設(shè)置動畫(注意:用forKeyPath而不是forKey)
[layer setValue:@.5 forKeyPath:@"transform.scale.x"];
四、隱式動畫 自建的layer是隱式動畫,view自帶的layer是顯式動畫
1、layer設(shè)置顯示的內(nèi)容,返回值是id,可以是一張圖片
layer.contents = (id)[UIImage imageNamed:@"QQlogin60@2x.png"].CGImage;
五、截圖
1、開啟位圖上下文
2、獲取當前上下文,也就是位圖上下文
3、設(shè)置裁剪區(qū)域
4、將視圖的圖層渲染到位圖上下文
5、從上下文獲取新的圖片
}