1.自定義控件
a.繼承某個(gè)控件
b.重寫(xiě)initWithFrame方法可以設(shè)置一些它的屬性
c.在layoutsubviews添加子控件的重寫(xiě)frame
d.提供一個(gè)屬性重寫(xiě)它的set方法
修飾符
用strong修飾OC對(duì)象以及NSString和Block ,沒(méi)添加到父控件上的控件
用weak修飾已經(jīng)被添加到父控件上的控件以及代理對(duì)象
用assign基本數(shù)據(jù)類(lèi)型披蕉、枚舉萎馅、結(jié)構(gòu)體(非OC對(duì)象)class類(lèi)型
用copy修飾一種情況下的NSString-->不確定賦值過(guò)程中用的是可變還是不可變字符串
2.簡(jiǎn)單的MVC
a.就是model模型vIewcontroll控制器view視圖.
3.xib的創(chuàng)建和story的創(chuàng)建
加載xib的方式有
[nsbundlemainnbundle ]loadNibName:"文件名"options :nil];
4.通過(guò)純代碼創(chuàng)建的初始化一定會(huì)調(diào)用initWithFrame方法
通過(guò)xib的創(chuàng)建和story的創(chuàng)建的一定會(huì)調(diào)用aweakFromNib方法.
通過(guò)xib的創(chuàng)建對(duì)于它加載視圖的時(shí)候會(huì)調(diào)用initWithCoder方法.
(1)awakeFromNib和initWithCoder:差別
awakeFromNib是初始化完畢調(diào)用并且從xib或者storyboard加載完畢就會(huì)調(diào)用
initWithCoder:只要對(duì)象是從文件解析來(lái)的扎阶,就會(huì)調(diào)用是初始化的時(shí)候調(diào)用
同時(shí)存在會(huì)先調(diào)用initWithCoder:
(2)initWithCoder: & initWithFrame:
initWithCoder:使用文件加載的對(duì)象調(diào)用(如從xib或stroyboard中創(chuàng)建)
initWithFrame:使用代碼加載的對(duì)象調(diào)用(使用純代碼創(chuàng)建)
注意:所以為了同時(shí)兼顧從文件和從代碼解析的對(duì)象初始化众旗,要同時(shí)在initWithCoder:和initWithFrame:中進(jìn)行初始化
5.拳皇設(shè)計(jì)的imageView的動(dòng)畫(huà)搖動(dòng)bottomLeft出來(lái)mode
kvc和Kvo的區(qū)別:
kvc可以快速的字典轉(zhuǎn)模型給私有的變量賦值給屬性賦值也行
// KVO :鍵值監(jiān)聽(tīng)
//作用:可以監(jiān)聽(tīng)某個(gè)對(duì)象屬性值的改變
/**
*給p對(duì)象添加一個(gè)監(jiān)聽(tīng)器
*
*Observer:監(jiān)聽(tīng)器(觀察者)
*KeyPath :監(jiān)聽(tīng)哪一個(gè)屬性值的改變
*/
[p addObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"asd"];
6.
在-(void)viewDidLoad里面調(diào)用
// self-sizing技術(shù)(iOS8開(kāi)始支持的)
//告訴tableView所有cell的真實(shí)高度是自動(dòng)計(jì)算的(根據(jù)你設(shè)置的約束計(jì)算)
self.tableView.rowHeight = UITableViewAutomaticDimension;
//告訴所有cell的估算高度
self.tableView.estimatedRowHeight =44;
if(status.isVip) {//是vip
self.vipImageView.hidden =NO;
self.nameLabel.textColor = [UIColor orangeColor];
}else{//不是vip
self.vipImageView.hidden =YES;
self.nameLabel.textColor = [UIColor blackColor];
}
if(status.picture) {//有配圖
self.pictureImageView.hidden =NO;
self.pictureImageView.image = [UIImage imageNamed:status.picture];
self.pictureHeight.constant =100;
self.pictureBottom.constant =10;
}else{//沒(méi)有配圖
self.pictureImageView.hidden =YES;
self.pictureHeight.constant =0;
self.pictureBottom.constant =0;
}
6.靜態(tài)cell:
當(dāng)界面處于不改變的狀態(tài)就是用靜態(tài)cell
在做一些“死”頁(yè)面的時(shí)候SB的靜態(tài)cell是很好的選擇,靜態(tài)cell也不是什么都不能做,靜態(tài)cell里的button還是可以拖到@implementation中形成IBAction的,但是是無(wú)法生成IBOutlet屬性或字段的。
即使你強(qiáng)行的給一個(gè)靜態(tài)的cell指定了一個(gè)cell的類(lèi)孝情,也是無(wú)法向其內(nèi)部拖入IBOutlet的。這就是靜態(tài)cell的局限性洒嗤,但是如果你要設(shè)置的數(shù)據(jù)不多還是可以考慮用靜態(tài)cell箫荡,因?yàn)槟憧梢酝ㄟ^(guò)給cell上的控件設(shè)tag來(lái)找到它從而賦值。
7.問(wèn)題1:簡(jiǎn)述registerNib:(nullableUINib *)nib forCellReuseIdentifier:(NSString *)identifier和registerClass:(nullableClass)cellClass forCellReuseIdentifier:(NSString *)identifier這2個(gè)方法的區(qū)別?
答:registerClass這個(gè)方法是根據(jù)ID注冊(cè)對(duì)應(yīng)的cell類(lèi)型,系統(tǒng)創(chuàng)建cell的方式是通過(guò)alloc/initWithStyle...
registerNib這個(gè)方法是根據(jù)ID注冊(cè)一個(gè)xib文件,系統(tǒng)創(chuàng)建cell的方式是通過(guò)加載xib文件.
問(wèn)題2:如何計(jì)算一段文字的寬度和高度?
答:第一種情況:如果label只有一行,通過(guò)sizeWithAttributes:這個(gè)方法,告知這段文字的字體和字體大小就可以計(jì)算這段文件的尺寸.
第二種情況:如果label需要換行計(jì)算高度,通過(guò)boundingRectWithSize: options: attributes:attributes context:這個(gè)方法,告知這段文字的字體和字體大小,并且在一個(gè)限制的尺寸內(nèi)計(jì)算這段文字的尺寸.
8.xib和storyBoard的創(chuàng)建:
1.xib創(chuàng)建的控制器首先要讓這個(gè)控制器擁有一個(gè)View就是連線到View
2.直接加載[self.view addSubview:[[[NSBundle mainBundle]loadNibNamed:@"One"owner:selfoptions:nil]lastObject]];
storyboard創(chuàng)建的要給storyboard綁定標(biāo)識(shí)其次在加載storyboardde視圖
例如:
UIStoryboard *story =[UIStoryboard storyboardWithName:@"OYVC"bundle:nil];//qwer為標(biāo)識(shí)符
[self.viewaddSubview:[story instantiateViewControllerWithIdentifier:@"qwer"].view];
9:為什么在遍歷一個(gè)數(shù)組的時(shí)候,不能一邊遍歷一邊刪除,這樣可能會(huì)導(dǎo)致什么問(wèn)題?
因?yàn)樵賱h除的同時(shí)遍歷的下標(biāo)將會(huì)隨著改變這樣就會(huì)導(dǎo)致數(shù)組遍歷混亂.
10.通知
//創(chuàng)建通知
1.NSNotification *note = [NSNotification notificationWithName:@"軍事新聞"object:comp1 userInfo:@{@"title":@"XXIIXIXIIXIXI"}];
//發(fā)布通知
2.[[NSNotificationCenter defaultCenter] postNotification:note];
1+2=[[NSNotificationCenter defaultCenter] postNotificationName:@"軍事新聞"object:comp1 userInfo:@{@"title":@"XXIIXIXIIXIXIUIUIUIUIUIUIUIUI"}];
[[NSNotificationCenter defaultCenter] postNotificationName:@"娛樂(lè)新聞"object:comp2 userInfo:@{@"title":@"XXIIXIXIIXIXIUIUIUIUIUIUIUIUI"}];
//匿名通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"娛樂(lè)新聞"object:niluserInfo:@{@"title":@"XXIIXIXIIXIXIUIUIUIUIUIUIUIUI"}];
//接收通知
[[NSNotificationCenter defaultCenter] addObserver:p1 selector:@selector(getNews:) name:@"軍事新聞"object:comp1];
[[NSNotificationCenter defaultCenter] addObserver:p2 selector:@selector(getNews:) name:@"娛樂(lè)新聞"object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:p2 selector:@selector(getNews:) name:@"娛樂(lè)新聞" object:nil];
addObserver是接收通知者selector:@selector(getNews:)是通知要執(zhí)行的方法name:@"軍事新聞"是通知消息的名字object是參數(shù)
11.通知的使用
a.注冊(cè)通知:[[NSNotificationCenter defaultCenter]postNotificationName:@"data"object:vc userInfo:@{@"mimi":self.textF.text}];
postNotificationName:消息的標(biāo)識(shí)假如是nil的話相當(dāng)于誰(shuí)都可以接收消息object:是將要接收消息者是發(fā)出者userInfo:是你要傳遞的數(shù)據(jù)也可說(shuō)是參數(shù).
b.接收通知也就是注冊(cè)通知
[[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector(changeValue:) name:@"data"object:nil];
addObserver :是要接收通知者elector:@selector(changeValue:)傳遞數(shù)據(jù)的方法name:是消息的標(biāo)識(shí)假如是nil的話就是什么消息都會(huì)接收object:是要發(fā)出者假如是nil的話誰(shuí)的消息都會(huì)接收
3.這就是實(shí)現(xiàn)數(shù)據(jù)傳遞的方法:
-(void)changeValue:(NSNotification *)notification{
NSDictionary *dic = [notification userInfo];
NSString *str = [dic objectForKey:@"mimi"];
self.textF.text = str;
}
12.屬性傳遞消息
接受者設(shè)置屬性
同時(shí)在發(fā)出者有數(shù)據(jù)的時(shí)候?qū)⒃摂?shù)據(jù)的值賦值給該屬性;
13.代理
1.設(shè)置一個(gè)協(xié)議并且要有一個(gè)傳遞數(shù)據(jù)的方法
2.發(fā)消息者設(shè)置一個(gè)代理屬性
3.在接收消消息者和發(fā)消息者同時(shí)出現(xiàn)的時(shí)候設(shè)置代理并且接收者需要遵守該協(xié)議即發(fā)出者.delegate =接受者;
4.接收者實(shí)現(xiàn)數(shù)據(jù)傳遞的方法
5.發(fā)消息者調(diào)用實(shí)現(xiàn)數(shù)據(jù)傳遞的方法.
14.控制器跳轉(zhuǎn):
1.modal跳轉(zhuǎn)
方法: presentViewController:/*需要跳轉(zhuǎn)的控制器(nonnull UIViewController *) */animated:(YES) completion:^{
跳轉(zhuǎn)之后執(zhí)行的方法
}
通過(guò)dismissViewControllerAnimated來(lái)返回前一個(gè)界面的渔隶。這是返回前一個(gè)界面的.
2.push POP跳轉(zhuǎn)
a.是給一根segua線綁定標(biāo)識(shí)在獲取跳轉(zhuǎn)的目標(biāo)控制器
//就是這種模式OYVC *vc = segue.destinationViewController;
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
OYVC *vc = segue.destinationViewController;
}
//再調(diào)用這個(gè)方法來(lái)實(shí)現(xiàn)跳轉(zhuǎn)
- (IBAction)go:(id)sender {
[selfperformSegueWithIdentifier:@"go"sender:nil];
}
//用代碼創(chuàng)建的
+ (instancetype)segueWithIdentifier:(nullableNSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination performHandler:(void(^)(void))performHandler NS_AVAILABLE_IOS(6_0);
- (instancetype)initWithIdentifier:(nullableNSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination NS_DESIGNATED_INITIALIZER;
b.回跳的話
[self.navigationController popViewControllerAnimated:YES];等方法
通過(guò)dismissViewControllerAnimated來(lái)返回前一個(gè)界面的羔挡。這是返回前一個(gè)界面的.也可以.
3、通過(guò)導(dǎo)航控制器UINavigationController
導(dǎo)航控制器:絕對(duì)是最常用的跳轉(zhuǎn)方法间唉,也是大家最熟悉的一種方式绞灼。每個(gè)控制器對(duì)象都有一個(gè)NavigationController屬性,NavigationController的view的是由導(dǎo)航條呈野,導(dǎo)航條控制的view,和棧頂控制器的view組成的低矮。
工作原理:通過(guò)棧的方式的來(lái)實(shí)現(xiàn)的,NavigationController展示永遠(yuǎn)就是棧頂?shù)目刂破鞯膙iew被冒。當(dāng)使用push方法的時(shí)候军掂,就將需要跳轉(zhuǎn)的控制器壓入棧中轮蜕,成為棧頂控制器;當(dāng)使用pop方法的時(shí)候良姆,就將控制器移出棧肠虽,原來(lái)跳轉(zhuǎn)之前的控制器重新成為棧頂控制器幔戏,被展現(xiàn)玛追;
需要注意的是:跳轉(zhuǎn)的時(shí)候,跳轉(zhuǎn)前的控制器不會(huì)移除闲延;導(dǎo)航欄(UINavigationBar)的屬性由棧頂控制器來(lái)決定痊剖。UINavigationBar支持appearance統(tǒng)一設(shè)置,但UINavigationItem不支持;
涉及到的類(lèi)詳解:
UINavigationBar :繼承至UIView垒玲,NavigaitonBar就是導(dǎo)航欄陆馁,位于屏幕的上方,管理整個(gè)NavigationController的navigationItem合愈,即類(lèi)似navigationcontroller一樣提供了一個(gè)棧來(lái)管理item叮贩。
UINavigationItem :繼承至NSObject,通過(guò)這個(gè)屬性來(lái)設(shè)置title佛析,prompt益老,leftBarButtonItem,titleView寸莫,,rightBarButtonItem捺萌,backBarButonItem等。
UIBarButtonItem :繼承至UIBarItem膘茎,UIBarItem繼承至UIButton桃纯。專(zhuān)門(mén)用來(lái)放在UIToolbar或者UINavigationBar的特殊button。
總結(jié):NavigationController直接控制ViewControllers披坏,并包含NavigaitonBar态坦。NavigaitonBar包含整個(gè)UINavigationItem的棧,管理整個(gè)NavigationController的UINavigationItem(NSArray *items屬性)棒拂。UINavigationItem包含了NavigaitonBar視圖的全部元素(如title,tileview,backBarButtonItem等)驮配,又受當(dāng)前棧頂控制器管理,即NavigaitonBar形成整個(gè)NavigationController的導(dǎo)航視圖着茸,然后每個(gè)NavigationController頁(yè)面的導(dǎo)航欄元素由所在頁(yè)面的UINavigationItem管理壮锻。即設(shè)置當(dāng)前頁(yè)面的左右barbutton。
4涮阔、UITabBarController
tabbar控制器猜绣,同樣是常用的界面切換方式,一般作為app的根界面的視圖控制器敬特。其實(shí)與其說(shuō)UITabBarController的界面跳轉(zhuǎn)掰邢,不如說(shuō)是界面切換牺陶,因?yàn)閁ITabBarController的界面跳轉(zhuǎn)其實(shí)就是UITabBarController的viewControllers數(shù)組中的幾個(gè)界面切換。只要設(shè)置好了UITabBarController的viewControllers數(shù)組就可以了辣之。也可以工廠自定義tabbar掰伸,通過(guò)selectedItem來(lái)控制。
結(jié)構(gòu)也類(lèi)似NavigationController
tableBar的添加底部的控制器有View Controllers添加子控制器.
15.通過(guò)storyboard加載控制器的方法
// Name:storyboard文件名
// nil = [NSBundle mainBundle]
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main"bundle:nil];
//加載Main.storyboard描述的控制器
// instantiateInitialViewController:加載箭頭指向的控制器
UIViewController *vc = [storyboard instantiateInitialViewController];
/通過(guò)xib加載控制器的步驟
// 1.創(chuàng)建xib文件
// 2.xib拖一個(gè)view去描述控制器的view!!!!!重點(diǎn)
// 3.告訴xib是描述控制器,設(shè)置file'owner為控制器,可以往控制器中拖線
// 4.連線,告訴控制器哪個(gè)view描述你的view
16.pch原理:會(huì)把pch里面的所有內(nèi)容導(dǎo)入到每個(gè)文件中去
pch作用:
1.pch存放公用的宏
2.pch存放公用的頭文件,分類(lèi)的頭文件
3.pch可以自定義Log
pch注意點(diǎn):
判斷下當(dāng)前是否是OC文件
*/
//每一個(gè)OC文件都會(huì)定義這個(gè)宏__OBJC__
#ifdef __OBJC__
//放OC
#import"UIImage+Image.h"
#define ABC 10
//判斷系統(tǒng)的版本號(hào)
#define iOS8([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
#define iPhone5 ([UIScreen mainScreen].bounds.size.height == 568)
//程序在調(diào)試階段的時(shí)候才需要打印
#ifdef DEBUG//調(diào)試階段
// ...表示宏里面的可變參數(shù)
// __VA_ARGS__函數(shù)里面可變參數(shù)
#define XMGLog(...)NSLog(__VA_ARGS__)
#else//發(fā)布階段
#define XMGLog(...)
#endif
16.日期的格式
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat =@"yyyy-MM-dd";
NSDate *date = [fmt dateFromString:@"1990-1-1"];
方法自己摸索一步步去理解
17.開(kāi)啟上下文模式(Quartz2D)
Quartz提供了5種類(lèi)型的Graphics Context怀估。Bitmap Graphics Context狮鸭、PDF Graphics Context、Window Graphics Context多搀、Layer Context概漱、Post Graphics Context壁顶。
a.圖形上下文
一定會(huì)執(zhí)行drawRect方法并且還要重繪[selfsetNeedsDisplay].
1.獲得圖形上下文2.設(shè)置繪畫(huà)路徑3將路徑描述好4將路徑添加到上下文中5將上下文渲染到圖中
// 1.獲取上下文
CGContextRef ctx= UIGraphicsGetCurrentContext();
// 2.設(shè)置繪圖信息/拼接路徑
UIBezierPath *path = [UIBezierPath bezierPath];
// 3.設(shè)置一個(gè)起點(diǎn)
[path moveToPoint:CGPointMake(10,10)];
// 4.添加一條直線到一個(gè)點(diǎn)
[path addLineToPoint:CGPointMake(100,100)];
// 5.添加一條直線到一個(gè)點(diǎn)
[path addLineToPoint:CGPointMake(150,60)];
// 5.把路徑添加到上下文
CGContextAddPath(ctx, path.CGPath);
// 6.把上下文渲染到視圖
CGContextStrokePath(ctx);
// stroke:描邊
// fill:填充
//設(shè)置線的樣式
CGContextSetLineJoin(ctx, kCGLineJoinBevel);
//設(shè)置頂角樣式
CGContextSetLineCap(ctx, kCGLineCapRound);
Current transformation matrix (CTM):當(dāng)前轉(zhuǎn)換矩陣
Clipping area:裁剪區(qū)域
Line:線
Accuracy of curve estimation (flatness):曲線平滑度
Anti-aliasing setting:反鋸齒設(shè)置
Color:顏色
Alpha value (transparency):透明度
Rendering intent:渲染目標(biāo)
Color space:顏色空間
Text:文本
Blend mode:混合模式
CGPathRef:用于向量圖堂油,可創(chuàng)建路徑披粟,并進(jìn)行填充或描畫(huà)(stroke)
CGImageRef:用于表示bitmap圖像和基于采樣數(shù)據(jù)的bitmap圖像遮罩。
CGLayerRef:用于表示可用于重復(fù)繪制(如背景)和幕后(offscreen)繪制的繪畫(huà)層
CGPatternRef:用于重繪圖
CGShadingRef从藤、CGGradientRef:用于繪制漸變
CGFunctionRef:用于定義回調(diào)函數(shù)催跪,該函數(shù)包含一個(gè)隨機(jī)的浮點(diǎn)值參數(shù)。當(dāng)為陰影創(chuàng)建漸變時(shí)使用該類(lèi)型
CGColorRef, CGColorSpaceRef:用于告訴Quartz如何解釋顏色
CGImageSourceRef,CGImageDestinationRef:用于在Quartz中移入移出數(shù)據(jù)
CGFontRef:用于繪制文本
CGPDFDictionaryRef,CGPDFObjectRef,CGPDFPageRef,CGPDFStream, CGPDFStringRef, and CGPDFArrayRef:用于訪問(wèn)PDF的元數(shù)據(jù)
CGPDFScannerRef, CGPDFContentStreamRef:用于解析PDF元數(shù)據(jù)
CGPSConverterRef:用于將PostScript轉(zhuǎn)化成PDF夷野。在iOS中不能使用懊蒸。
2.位圖上下文:
// 1.開(kāi)啟上下文
UIGraphicsBeginImageContextWithOptions(view.bounds.size,NO,0.0);
// 2.獲取當(dāng)前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 3.把控制器圖層渲染到上下文
[view.layer renderInContext:ctx];
// 4.取出新圖片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//圖片保存到本地相冊(cè)的方法:::
UIImageWriteToSavedPhotosAlbum(newImage,self,@selector(image:didFinishSavingWithError:contextInfo:),nil);
//當(dāng)寫(xiě)入完成時(shí)調(diào)用即是照片讀取完畢后會(huì)進(jìn)來(lái)
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void*)contextInfo {
NSLog(@"saveCom");
}
- (IBAction)photo:(id)sender {
//彈出系統(tǒng)相冊(cè)選擇照片
UIImagePickerController *pickVC = [[UIImagePickerController alloc] init];
//設(shè)置照片來(lái)源
pickVC.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
//只要實(shí)現(xiàn)代理方法,必須得要手去關(guān)閉控制器
pickVC.delegate =self;
//modal
[selfpresentViewController:pickVC animated:YEScompletion:nil];
}
//選擇照片完畢后會(huì)進(jìn)來(lái)
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(@"%@",info);
UIImage *image = info[UIImagePickerControllerOriginalImage];
//NSData *data = UIImagePNGRepresentation(image);
//[data writeToFile:@"/Users/apple/Desktop/choose.png" atomically:YES];
HanleImageUIView *hanleV = [[HanleImageUIView alloc] init];
hanleV.frame =self.drawView.frame;
hanleV.backgroundColor = [UIColor clearColor];
hanleV.image = image;
hanleV.delegate =self;
[self.view addSubview:hanleV];
//把選擇圖片繪制畫(huà)板當(dāng)中
//self.drawView.image = image;
[selfdismissViewControllerAnimated:YEScompletion:nil];
}
18.cell釋放池的問(wèn)題cell能夠重復(fù)利用
當(dāng)前tableview界面當(dāng)當(dāng)一個(gè)消失后一個(gè)出現(xiàn)的時(shí)候后一個(gè)的內(nèi)存地址就是第一個(gè)的內(nèi)存地址這樣就解決了內(nèi)存地址的問(wèn)題就會(huì)有重用機(jī)制這樣的話內(nèi)存就會(huì)大大的減少
//cell的創(chuàng)建系統(tǒng)的釋放池內(nèi)
UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier:ID];
//判斷釋放池內(nèi)有沒(méi)有cell
//第一種方式
if( !cell ) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];
}
//第二種注冊(cè)的方式
1.類(lèi)的注冊(cè)
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
2.xib的注冊(cè)
[self.tableView registerNib:<#(nullable UINib *)#> forCellReuseIdentifier:ID];
//第三種是自己自定義cell可以在xib或者storyBoard里面設(shè)置cell的標(biāo)識(shí)
//分割線顏色
self.tableView.separatorColor = [UIColor redColor];
//隱藏分割線
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
//自定義不等高cell的做法
在模型中增加一個(gè)cellHeight屬性,用來(lái)存放對(duì)應(yīng)cell的高度
在cell的模型屬性set方法中調(diào)用[selflayoutIfNeed]方法強(qiáng)制布局扫责,然后計(jì)算出模型的cellheight屬性值
在控制器中實(shí)現(xiàn)tableView:estimatedHeightForRowAtIndexPath:方法榛鼎,返回一個(gè)估計(jì)高度,比如200
在控制器中實(shí)現(xiàn)tableView:heightForRowAtIndexPath:方法鳖孤,返回cell的真實(shí)高度(模型中的cellHeight屬性
19.單粒單例模式的替代一勞永逸
#define SingleH(name) +(instancetype)share##name;
#if __has_feature(objc_arc)
///ARC
#define SingleM(name) static id_instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}\
+(instancetype)share##name\
{\
return [[self alloc]init];\
}\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}
#else
//MRC
#define SingleM(name) static id_instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}\
+(instancetype)share##name\
{\
return [[self alloc]init];\
}\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
-(oneway void)release\
{}\
\
-(instancetype)retain\
{\
return _instance;\
}\
\
-(NSUInteger)retainCount\
{\
return MAXFLOAT;\
}
#endif
19.沙盒
Documents :會(huì)備份&不允許(X)//很重要
Library
caches
perference偏好設(shè)置
tmp :臨時(shí)數(shù)據(jù)
4.數(shù)據(jù)存儲(chǔ)
1.Documents
獲取方法:NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES)[0];
//存放重要數(shù)據(jù).iTunes同步設(shè)備時(shí)會(huì)備份
2.tmp
獲取方法:NSTemporaryDirectory();
//存放臨時(shí)文件,系統(tǒng)會(huì)隨機(jī)刪除
3.Caches
獲取方法:NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES)[0];
//存放大體積,不必要備份文件
4.Preferences
獲取方法:[NSUserDefaults standardUserDefaults]
//存放少量數(shù)據(jù).iTunes同步設(shè)備時(shí)會(huì)備份
2.數(shù)據(jù)存儲(chǔ)
1.plist
pilst只支持系統(tǒng)自帶的類(lèi)型(如:NSString,NSArray,NSDictionary,NSData,NSNumber等)
1.寫(xiě)入:writeToFile
2.讀取:...WithContentOfFile(如:arrayWithContentOfFile)
2.偏好設(shè)置
1.取得偏好設(shè)置對(duì)象(NSUserDefaults)
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
2.寫(xiě)入到文件夾
[def setObject:obj forKey:key];//oc類(lèi)對(duì)應(yīng)setObject,bool類(lèi)型對(duì)應(yīng)setBool等...
3.讀取內(nèi)容
[def objectForKey:obj];//oc類(lèi)對(duì)應(yīng)object,NSInteger對(duì)應(yīng)integer等...
3.歸檔
1.寫(xiě)入用NSKeyedArchjver
1.選擇要存儲(chǔ)的位置(filePath)
2.系統(tǒng)自帶類(lèi)(如:NSArray,NSDictionary)直接使用
3.自定義類(lèi)需遵守NSCoding協(xié)議,并重寫(xiě)encodeWithCoder方法(例子為name屬性)
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
}
4.調(diào)用[NSKeyedArchjver archiveRootObject:object toFile:filePath];
2.讀取用NSKeyedUnArchjver
1.獲取要讀取文件的位置(filePath)
2.系統(tǒng)自帶類(lèi)(如:NSArray,NSDictionary)直接使用
3.自定義類(lèi)需遵守NSCoding協(xié)議,并重寫(xiě)initWithCoder方法(例子為name屬性)
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if(self= [superinit]){
self.name = [aDecoder decodeObjectForKey:@"name"];
}
returnself;
}
4.調(diào)用[NSKeyedUnArchjver unarchiveObjectWithFile:filePath]
歸檔:自定義對(duì)象一般使用歸檔,為什么自定義對(duì)象需要?dú)w檔,plist存儲(chǔ)不能存儲(chǔ)自定義對(duì)象其實(shí)際操作跟字典差不多就是得遵守nscoding的協(xié)議
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullableinstancetype)initWithCoder:(NSCoder *)aDecoder;
假如你要存檔和解檔的話都要寫(xiě)這兩個(gè)方法方法也要看著屬性的類(lèi)型進(jìn)去解歸檔.
要使用歸檔的話都要遵守nscoding這個(gè)協(xié)議
首先進(jìn)行保存的操作:就是將數(shù)據(jù)讀取進(jìn)去假如寫(xiě)入模型的時(shí)候要進(jìn)行一
如何進(jìn)行解檔的操作
解析文件的時(shí)候調(diào)用
//作用:解析xib,storyboard調(diào)用
- (id)initWithCoder:(NSCoder *)aDecoder
{
//這里必須調(diào)用[super initWithCoder:aDecoder],super ->UIView
//什么時(shí)候調(diào)用[super initWithCoder:aDecoder],只要父類(lèi)遵守了NSCoding協(xié)議,就調(diào)用[super initWithCoder:aDecoder]
if(self= [superinitWithCoder:aDecoder]) {
NSLog(@"%s",__func__);
}
returnself;
}
20.下載圖片的整體思路:
1.首先判斷內(nèi)存緩存有沒(méi)有圖片2假如沒(méi)有的話就要保存到內(nèi)存中3在保存中還要看它有沒(méi)有在子線程中如果在的話啥都不做不在的話就要?jiǎng)?chuàng)建子線程將圖片下載的過(guò)程加到子隊(duì)列中而且還要檢查圖片是不是為空不然的話會(huì)一直有任務(wù)在進(jìn)行就會(huì)一直開(kāi)子進(jìn)程在子進(jìn)程中還要跳轉(zhuǎn)到主進(jìn)程去顯示圖片最后將子進(jìn)程添加到隊(duì)列中并且保存隊(duì)列到字典中去進(jìn)行下一次判斷子進(jìn)程還要不要開(kāi)就是執(zhí)行中任務(wù)有沒(méi)有不然會(huì)造成任務(wù)多次運(yùn)行.
//假如圖片為空的話移除所有隊(duì)列里面的加載
if(newImage ==nil) {
[self.opearations removeObjectForKey:item.icon];
}
[self.images setValue:newImage forKey:item.icon];
[data writeToFile:filePath atomically:YES];
//刷新tabelView的方法
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.tableView reloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationTop];
}];
1)UI卡頓--->開(kāi)子線程下載圖片
圖片不顯示(fram=0)--->刷新指定的行
重復(fù)下載的問(wèn)題(因?yàn)閳D片下載操作需要花費(fèi)時(shí)間,在該時(shí)間段內(nèi)部此image有需要顯示)
對(duì)圖片的下載操作進(jìn)行緩存--->操作緩存
2)重復(fù)下載的問(wèn)題-->內(nèi)存緩存
*/
//二級(jí)緩存
/*
顯示-->內(nèi)存緩存-->下載
顯示-->內(nèi)存緩存-->磁盤(pán)緩存-->下載
*/
21.SDWebImage下載圖片框架的作用:
1).為cocoa touch提供一個(gè)UIimageView的分類(lèi),加載圖片并進(jìn)行緩存處理
2).異步下載圖片
3).異步存儲(chǔ)器+具備自動(dòng)緩存過(guò)程處理的磁盤(pán)映像緩存
4).支持GIF播放
5).支持WebP格式
6).背景圖片解壓縮
7).保證同一個(gè)圖片Url不被多次下載
8).保證錯(cuò)誤的URL不被反復(fù)下載
9).保證不會(huì)阻塞主線程
10).高性能
11).使用GCD和ARC機(jī)制
12).支持Ara64架構(gòu)
/*
1)clear先把之前的緩存文件夾刪除,然后重新創(chuàng)建一個(gè)新的文件夾是暴力刪除
clean先刪除過(guò)期的文件,然后計(jì)算剩余緩存文件的大小(currrentSize)>maxSize,繼續(xù)刪除(按照緩存文件創(chuàng)建的時(shí)間順序來(lái)刪除的),直到currrentSize <= maxSize
2)默認(rèn)過(guò)期時(shí)間:1個(gè)星期
3)內(nèi)存緩存機(jī)制(用什么來(lái)做內(nèi)存緩存?是字典嗎?) NSCache是專(zhuān)門(mén)用來(lái)做緩存處理的
4)最大并發(fā)數(shù)量maxConcurrentOperationCount = 6
5)隊(duì)列中任務(wù)的執(zhí)行方式:
SDWebImageDownloaderExecutionOrder
SDWebImageDownloaderFIFOExecutionOrder(FIFO)默認(rèn)
SDWebImageDownloaderLIFOExecutionOrder(lIFO)(通過(guò)設(shè)置依賴來(lái)實(shí)現(xiàn))
6)默認(rèn)的緩存路徑:~/Library/Caches/default/com.hackemist.SDWebImageCache.default/...
7)圖片保存的名稱(chēng)處理方式:url進(jìn)行MD5加密echo -n "url" | md5
8)播放GIF圖片, GIF圖片播放原理ImageIO
9)如何判斷圖片的類(lèi)型:得到圖片的二進(jìn)制數(shù)據(jù)的第一個(gè)字節(jié)
10)該框架內(nèi)部通過(guò)NSURLConnection建立網(wǎng)絡(luò)連接發(fā)送請(qǐng)求下載圖片
11)默認(rèn)的請(qǐng)求超時(shí)的時(shí)間是_downloadTimeout = 15
12)該框架內(nèi)部對(duì)內(nèi)存警告的處理方式:內(nèi)部會(huì)監(jiān)聽(tīng)系統(tǒng)發(fā)出的系統(tǒng)警告通知,然后清理內(nèi)存緩存
13)NSCache使用方法和可變的字典類(lèi)似(80%),線程安全&可以自動(dòng)的清理緩存數(shù)據(jù)
14)計(jì)算圖片的成本:image.size.height * image.size.width * image.scale * image.scale
15)保證錯(cuò)誤url不被反復(fù)嘗試下載?內(nèi)部設(shè)置了一個(gè)url黑名單NSMutableSet
*/
下載圖片框架的使用:
1.1)下載圖片并顯示(內(nèi)存緩存&磁盤(pán)緩存)
/*
第一個(gè)參數(shù):圖片的url地址
第二個(gè)參數(shù):設(shè)置的占位圖片
*/
[self.imageView sd_setImageWithURL:[NSURL URLWithString:URL] placeholderImage:[UIImage imageNamed:image]];
2.下載圖片顯示并計(jì)算下載進(jìn)度(內(nèi)存緩存&磁盤(pán)緩存&下載進(jìn)度)
/*
第一個(gè)參數(shù):圖片的url地址
第二個(gè)參數(shù):設(shè)置的占位圖片
第三個(gè)參數(shù):下載圖片選項(xiàng)(策略)
第四個(gè)參數(shù):進(jìn)度回調(diào)blockreceivedSize:已經(jīng)下載的數(shù)據(jù)大小expectedSize:圖片的總大小
第五個(gè)參數(shù):completed圖片下載結(jié)束回調(diào)(成功|失斦哂椤)
image:下載后得到的圖片,如果下載失敗苏揣,那么image的值為nil
error:錯(cuò)誤信息黄鳍,如果失敗,則error有值
cacheType:圖片來(lái)源(枚舉:內(nèi)存緩存|磁盤(pán)緩存|直接下載)
imageURL:下載圖片的url
*/
sd_setImageWithURL:[NSURL URLWithString:url]placeholderImage:[UIImage imageNamed:占位圖片] options:SDWebImageProgressiveDownload progress:^(NSInteger receivedSize, NSInteger expectedSize) {
NSLog(@"%f",1.0* receivedSize/expectedSize);//進(jìn)度值得算法
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
}
3)下載圖片不顯示并監(jiān)聽(tīng)下載進(jìn)度(內(nèi)存緩存&磁盤(pán)換次&下載進(jìn)度)
-(void)download3
{
//使用管理者下載圖片
[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:URL] options:0progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType,BOOLfinished, NSURL *imageURL) {
NSLog(@"+++++%@",[NSThread currentThread]);
self.imageView.image = image;
switch(cacheType) {
caseSDImageCacheTypeNone:
NSLog(@"直接下載");
break;
caseSDImageCacheTypeDisk:
NSLog(@"磁盤(pán)緩存");
break;
caseSDImageCacheTypeMemory:
NSLog(@"內(nèi)存緩存");
break;
default:
break;
}
}];
}
4)下載圖片不顯示且不做任何的緩存處理
-(void)download4
{
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:動(dòng)圖的URL ] options:0progress:^(NSInteger receivedSize, NSInteger expectedSize) {
NSLog(@"%f",1.0* receivedSize/expectedSize);
} completed:^(UIImage *image, NSData *data, NSError *error,BOOLfinished) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = [UIImage sd_animatedGIFWithData:data];
}];
}];
}
5)接收到系統(tǒng)級(jí)內(nèi)存警告時(shí)如何處理(面試)
//(1)取消當(dāng)前正在進(jìn)行的所有下載操作
[[SDWebImageManager sharedManager] cancelAll];
//(2)清除緩存數(shù)據(jù)
//cleanDisk:刪除過(guò)期的文件數(shù)據(jù)平匈,計(jì)算當(dāng)前未過(guò)期的已經(jīng)下載的文件數(shù)據(jù)的大小框沟,如果發(fā)現(xiàn)該數(shù)據(jù)大小大于我們?cè)O(shè)置的最大緩存數(shù)據(jù)大小,那么程序內(nèi)部會(huì)按照按文件數(shù)據(jù)緩存的時(shí)間從遠(yuǎn)到近刪除增炭,知道小于最大緩存數(shù)據(jù)為止忍燥。
//clearMemory:直接刪除文件,重新創(chuàng)建新的文件夾
//[[SDWebImageManager sharedManager].imageCache cleanDisk];
[[SDWebImageManager sharedManager].imageCache clearMemory];
6)播放gif圖片
(1)播放GiF圖片部分過(guò)程解析
a.把用戶傳入的gif圖片->NSData
b.根據(jù)該Data創(chuàng)建一個(gè)圖片數(shù)據(jù)源(NSData->CFImageSourceRef)
c.計(jì)算該數(shù)據(jù)源中一共有多少幀隙姿,把每一幀數(shù)據(jù)取出來(lái)放到圖片數(shù)組中
d.根據(jù)得到的數(shù)組+計(jì)算的動(dòng)畫(huà)時(shí)間-》可動(dòng)畫(huà)的image
e.[UIImage animatedImageWithImages:images duration:duration];
(2)如何使用
-(void)gif
{
//self.imageView.image = [UIImage imageNamed:@"123"];不可用
UIImage *image = [UIImage sd_animatedGIFNamed:@"123"];
self.imageView.image = image;
}
22.NSCache與NSDictionary的對(duì)比:要遵守代理的哦
1.NSCache可以設(shè)置代理
2.NSCache可以設(shè)置緩存的成本即當(dāng)超過(guò)了這個(gè)成本的時(shí)候會(huì)自動(dòng)刪除從前往后刪.
3.NSCache的線程是安全的
totalCostLimit:緩存空間的最大總成本梅垄,超出上限會(huì)自動(dòng)回收對(duì)象。默認(rèn)值為0输玷,表示沒(méi)有限制
countLimit:能夠緩存的對(duì)象的最大數(shù)量队丝。默認(rèn)值為0靡馁,表示沒(méi)有限制
evictsObjectsWithDiscardedContent:標(biāo)識(shí)緩存是否回收廢棄的內(nèi)容
//NSCache的基本使用(如何存數(shù)據(jù)|如何取數(shù)據(jù))~和可變字典類(lèi)似
當(dāng)內(nèi)部開(kāi)始清理數(shù)據(jù)的時(shí)候調(diào)用
-(void)cache:(NSCache *)cache willEvictObject:(id)obj;
23.新版本特性界面控制器
1.根據(jù)對(duì)應(yīng)版本號(hào)來(lái)確定是否新特性界面控制器
self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
//2.設(shè)置根控制器
//2.1根據(jù)當(dāng)前版本和上一次的版本進(jìn)行判斷
//2.2獲取當(dāng)前版本號(hào)
NSString *curVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];
//2.3獲取上一次的版本號(hào)
NSString *lastVersion = [[NSUserDefaults standardUserDefaults]objectForKey:@"version"];
//2.4根據(jù)比較確定是否存儲(chǔ)版本
if([curVersion isEqualToString:lastVersion]) {
XMGMainVc *mainVc = [[XMGMainVc alloc]init];
self.window.rootViewController = mainVc;
//
}else{//存儲(chǔ)版本,當(dāng)前版本和上一次不一樣,顯示新特性界面
NSUserDefaults *defaultData = [NSUserDefaults standardUserDefaults];
[defaultData setObject:curVersion forKey:@"version"];
[defaultData synchronize];
XMGNewFeatureVc *newVc = [[XMGNewFeatureVc alloc]init];
self.window.rootViewController = newVc;
}
//3.可見(jiàn)
[self.window makeKeyAndVisible];
24.位移枚舉
1.//純C語(yǔ)言風(fēng)格
typedefenum: NSUInteger {
MyEnumValueA,
MyEnumValueB,
MyEnumValueC,
} myType;
//純OC語(yǔ)言風(fēng)格
typedefNS_ENUM(NSUInteger, myOCType) {
MyEnumValue1,
MyEnumValue2,
MyEnumValue3,
};
//位移枚舉
typedefNS_OPTIONS(NSUInteger, myWeiYiType) {
MyEnumValueA1 =1<<0,
MyEnumValueB2 =1<<1,
MyEnumValueC3 =1<<2,
};
2.位移枚舉相關(guān)說(shuō)明
特點(diǎn):通過(guò)使用位移枚舉可以實(shí)現(xiàn)一個(gè)參數(shù)實(shí)現(xiàn)傳遞多個(gè)操作
原理:按位與只要有0則為0机久,按位或只要有1則為1
技巧:如果位移枚舉的第一個(gè)選項(xiàng)為0臭墨,那么在傳遞參數(shù)的時(shí)候默認(rèn)可以傳0,傳0性能最優(yōu)膘盖,不做額外的操作
25.NSTimer和GCD的定時(shí)器有什么區(qū)別胧弛?
1.GCD的定時(shí)器比nstimer更加精確
2.GCD的定時(shí)器不用依賴runloop而nstimer沒(méi)有加入到runloop中將不會(huì)運(yùn)行
3.[NSTimer scheduledTimerWithTimeInterval:3.0target:selfselector:@selector(task) userInfo:nilrepeats:YES];//默認(rèn)已經(jīng)添加到runloop中
假如不用這個(gè)方法就要加到runLoop中;
4.
//1.創(chuàng)建一個(gè)GCD的定時(shí)器
/*
第一個(gè)參數(shù):DISPATCH_SOURCE_TYPE_TIMER定時(shí)器
第二個(gè)參數(shù):描述信息
第三個(gè)參數(shù):總是穿0
第四個(gè)參數(shù):隊(duì)列(決定GCD要執(zhí)行的任務(wù)在哪個(gè)線程中調(diào)用的并發(fā)隊(duì)列--子線程中調(diào)用)
*/
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, dispatch_get_main_queue());
//2.設(shè)置定時(shí)器
/*
第一個(gè)參數(shù):定時(shí)器對(duì)象
第二個(gè)參數(shù):從什么時(shí)候開(kāi)始計(jì)時(shí)DISPATCH_TIME_NOW現(xiàn)在
第三個(gè)參數(shù):間隔時(shí)間2.0 ns
第四個(gè)參數(shù):精準(zhǔn)度允許的誤差絕對(duì)精準(zhǔn)~0
*/
//dispatch_time_t t = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW,2.0* NSEC_PER_SEC,0* NSEC_PER_SEC);
//3.設(shè)置定時(shí)器的任務(wù)
dispatch_source_set_event_handler(timer, ^{
NSLog(@"==GCD===%@",[NSThread currentThread]);//任務(wù)塊
});
//4.恢復(fù)定時(shí)器
dispatch_resume(timer);
//一定要這句要強(qiáng)應(yīng)用它不然創(chuàng)建的定時(shí)器對(duì)象就會(huì)掛掉
self.timer = timer;
26.Runloop原理:
1.程序一啟動(dòng)就會(huì)有一個(gè)主runloop開(kāi)啟
2)在iOS開(kāi)發(fā)中有兩套api來(lái)訪問(wèn)Runloop
a.foundation框架[NSRunloop]
b.core foundation框架[CFRunloopRef]互換的格式是例如: mainRunloop.getCFRunLoop
2./子線程和runloop的關(guān)系
/*
1)一一對(duì)應(yīng)的
2)主線程對(duì)應(yīng)的runloop默認(rèn)已經(jīng)開(kāi)啟了,子線程對(duì)應(yīng)的runloop需要主動(dòng)創(chuàng)建
3)如何創(chuàng)建子線程對(duì)應(yīng)的runloop :[NSRunLoop currentRunLoop](該方法本身是懶加載的,第一次調(diào)用該方法的時(shí)候如果發(fā)現(xiàn)runloop不存在那么會(huì)直接創(chuàng)建一個(gè))
4)runloop是需要開(kāi)啟
*/
3.a.CFRunloopRef//創(chuàng)建runloop對(duì)象
b.CFRunloopModeRef【Runloop的運(yùn)行模式】
c.CFRunloopSourceRef【Runloop要處理的事件源】
d.CFRunloopTimerRef【Timer事件】
e.CFRunloopObserverRef【Runloop的觀察者(監(jiān)聽(tīng)者)】
注意點(diǎn):
01.CFRunloopModeRef代表著Runloop的運(yùn)行模式
02.一個(gè)Runloop中可以有多個(gè)mode,一個(gè)mode里面又可以有多個(gè)source\observer\timer等等
03.每次runloop啟動(dòng)的時(shí)候,只能指定一個(gè)mode,這個(gè)mode被稱(chēng)為該Runloop的當(dāng)前mode
04.如果需要切換mode,只能先退出當(dāng)前Runloop,再重新指定一個(gè)mode進(jìn)入
05.這樣做主要是為了分割不同組的定時(shí)器等衔憨,讓他們相互之間不受影響
06.系統(tǒng)默認(rèn)注冊(cè)了5個(gè)mode
a.kCFRunLoopDefaultMode:App的默認(rèn)Mode叶圃,通常主線程是在這個(gè)Mode下運(yùn)行
b.UITrackingRunLoopMode:界面跟蹤Mode袄膏,用于ScrollView追蹤觸摸滑動(dòng)践图,保證界面滑動(dòng)時(shí)不受其他Mode影響
c.UIInitializationRunLoopMode:在剛啟動(dòng)App時(shí)第進(jìn)入的第一個(gè)Mode,啟動(dòng)完成后就不再使用
d.GSEventReceiveRunLoopMode:接受系統(tǒng)事件的內(nèi)部Mode沉馆,通常用不到
e.kCFRunLoopCommonModes:這是一個(gè)占位用的Mode码党,不是一種真正的Mode
CFRunLoopObserverRef//觀察者
這個(gè)僅供內(nèi)部參考實(shí)際開(kāi)發(fā)中基本用不到
1.創(chuàng)建監(jiān)聽(tīng)者
/*
第一個(gè)參數(shù):分配存儲(chǔ)空間
第二個(gè)參數(shù):告知要監(jiān)聽(tīng)的是哪種狀態(tài)
第三個(gè)參數(shù):持續(xù)監(jiān)聽(tīng)runloop狀態(tài)
第四個(gè)參數(shù):優(yōu)先級(jí)0
第五個(gè)參數(shù):activity runloop當(dāng)前的狀態(tài)
*/
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities,YES,0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
/*
kCFRunLoopEntry = (1UL << 0),進(jìn)入
kCFRunLoopBeforeTimers = (1UL << 1),即將處理timer事件
kCFRunLoopBeforeSources = (1UL << 2),將處理soure事件
kCFRunLoopBeforeWaiting = (1UL << 5),即將進(jìn)入休眠
kCFRunLoopAfterWaiting = (1UL << 6),被喚醒
kCFRunLoopExit = (1UL << 7),runloop退出
kCFRunLoopAllActivities = 0x0FFFFFFFU
*/
2.給對(duì)應(yīng)的runloop添加監(jiān)聽(tīng)者并且制定監(jiān)聽(tīng)的是哪種運(yùn)行模式
/*
第一個(gè)參數(shù):runloop對(duì)象本身
第二個(gè)參數(shù):監(jiān)聽(tīng)者(觀察者)
第三個(gè)參數(shù):runloop的運(yùn)行模式
*/
CFRunLoopAddObserver(CFRunLoopGetCurrent(),observer, kCFRunLoopDefaultMode);
4.Runloop應(yīng)用
1)NSTimer
2)ImageView顯示:控制方法在特定的模式下可用
3)PerformSelector
4)常駐線程:在子線程中開(kāi)啟一個(gè)runloop
5)自動(dòng)釋放池
第一次創(chuàng)建:進(jìn)入runloop的時(shí)候
最后一次釋放:runloop退出的時(shí)候
//其它創(chuàng)建和釋放:當(dāng)runloop即將休眠的時(shí)候會(huì)把之前的自動(dòng)釋放池釋放,然后重新創(chuàng)建一個(gè)新的釋放池//????
27.自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà):
1.在要跳轉(zhuǎn)的控制器實(shí)現(xiàn)系統(tǒng)跳轉(zhuǎn)
ZJViewController *zjVc = [[ZJViewController alloc] init];
[selfpresentViewController:zjVc animated:YEScompletion:nil];
2.給要跳轉(zhuǎn)的控制器設(shè)置代理為self,設(shè)置跳轉(zhuǎn)方式為UIModalPresentationCustom
zjVc.modalPresentationStyle = UIModalPresentationCustom;
zjVc.transitioningDelegate =self;
3.遵守UIViewControllerTransitioningDelegate協(xié)議,實(shí)現(xiàn)方法
- (nullableUIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source{
return[[UIPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
}
4.需實(shí)現(xiàn)UIPresentationController里的方法,繼承自UIPresentationController寫(xiě)一個(gè)自己的跳轉(zhuǎn)控制器
//這里為ZJPresentationController
將第3步返回的對(duì)象改為這種類(lèi)型
return[[ZJPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
5.實(shí)現(xiàn)跳轉(zhuǎn)控制器(ZJPresentationController)的方法
- (void)containerViewWillLayoutSubviews{
//設(shè)置控制器的大小位置,不設(shè)置不會(huì)顯示出來(lái)
self.presentedView.frame =self.containerView.bounds;
}
- (void)presentationTransitionWillBegin{
[self.containerView addSubview:self.presentedView];
}
- (void)dismissalTransitionDidEnd:(BOOL)completed{
[self.presentedView removeFromSuperview];
}
6.設(shè)置動(dòng)畫(huà)的代理
只要遵守了UIViewControllerAnimatedTransitioning協(xié)議的都可以(復(fù)雜時(shí)新建一個(gè)對(duì)象專(zhuān)門(mén)管理動(dòng)畫(huà))
- (nullableid)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:
//返回控制器彈出時(shí)動(dòng)畫(huà)的代理
- (nullableid)animationControllerForDismissedController:(UIViewController *)dismissed
//返回控制器銷(xiāo)毀時(shí)動(dòng)畫(huà)的代理
7.代理中實(shí)現(xiàn)動(dòng)畫(huà)方法
- (void)animateTransition:(id)transitionContext
如果控制器彈出,銷(xiāo)毀都有動(dòng)畫(huà),則需聲明一個(gè)屬性來(lái)記錄彈出還是銷(xiāo)毀狀態(tài)
@property(nonatomic,assign)BOOLpresented;
并且在第6步中返回時(shí)給這個(gè)代理的presented屬性賦值(YES/NO)
然后根據(jù)這個(gè)屬性來(lái)做動(dòng)畫(huà)
[transitionContext viewForKey:UITransitionContextToViewKey];
//獲取彈出時(shí)的view
[transitionContext viewForKey:UITransitionContextFromViewKey]
//獲取銷(xiāo)毀時(shí)的view
[transitionContext completeTransition:YES];
//動(dòng)畫(huà)完成時(shí)一定要通知系統(tǒng)
假如要在首層disMiss掉需要通過(guò)創(chuàng)建手勢(shì)的方法
[self.presentedVC disMiss........]
攔截手勢(shì)的方法首先遵守手勢(shì)代理設(shè)置代理實(shí)現(xiàn)代理方法在代理方法中確定手勢(shì)的范圍.
cgpoint Point = [touch locationinView:手勢(shì)的View];
BOOLpresent = CGRectContainsPoint(self.presentedView.frame, point);
28.控制器的生命周期的方法以及調(diào)用的順序
//當(dāng)控制器View加載完畢時(shí)調(diào)用
- (void)viewDidLoad {
[superviewDidLoad];
NSLog(@"%s",__func__);
}
一般調(diào)用一次
//當(dāng)控制器View即將顯示時(shí)調(diào)用
- (void)viewWillAppear:(BOOL)animated {
[superviewWillAppear:animated];
NSLog(@"%s",__func__);
}
//當(dāng)控制器View顯示完畢時(shí)調(diào)用
- (void)viewDidAppear:(BOOL)animated {
[superviewDidAppear:animated];
NSLog(@"%s",__func__);
}
//當(dāng)控制器View即將布局子控件時(shí)調(diào)用
- (void)viewWillLayoutSubviews {
[superviewWillLayoutSubviews];
NSLog(@"%s",__func__);
}
//當(dāng)控制器View布局子控件完畢時(shí)調(diào)用
- (void)viewDidLayoutSubviews {
[superviewDidLayoutSubviews];
NSLog(@"%s",__func__);
}
//當(dāng)控制器View既將消失時(shí)調(diào)用
- (void)viewWillDisappear:(BOOL)animated {
[superviewWillDisappear:animated];
NSLog(@"%s",__func__);
}
//當(dāng)控制器View消失完畢時(shí)調(diào)用
- (void)viewDidDisappear:(BOOL)animated {
[superviewDidDisappear:animated];
NSLog(@"%s",__func__);
}
29.控制器的跳轉(zhuǎn)的方式以及數(shù)據(jù)傳遞的方式
1.手動(dòng)創(chuàng)建是由一個(gè)view跳轉(zhuǎn)到另外一個(gè)view;必須有標(biāo)識(shí)符的
2.用代碼根據(jù)標(biāo)識(shí)去跳轉(zhuǎn)
3.自動(dòng)創(chuàng)建是直接跳轉(zhuǎn)的點(diǎn)擊控件自動(dòng)轉(zhuǎn)到下一個(gè)控制器
4.數(shù)據(jù)傳遞的方式正向傳遞和逆向傳遞
5.正向傳遞
[[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector(textChange) name:nilobject:self.accountTextF]
observer :
name:是通知的名字
object:是發(fā)通知的的人
selector :是方法
代理:
1.代理者:接收消息的人
2.被代理者:是發(fā)消息的人'
3.屬性:定義屬性@property(nonatimic,strong)id<協(xié)議名稱(chēng)>屬性名稱(chēng);
4.調(diào)用代理;
1.plist
1.1tmp:
1.2doucument
block的做法
//起別名
typedefvoid(^contanctBlock ) (XMGContactItem *);
//屬性
@property(nonatomic,copy)contanctBlock contactBlock;
調(diào)用block
if(self.contactBlock) {
self.contactBlock(item);
}
//在跳轉(zhuǎn)前之前會(huì)調(diào)用這個(gè)方法
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
XMGAddVC_3 *addVC = segue.destinationViewController;
addVC.contactBlock = ^(XMGContactItem *item){
//實(shí)現(xiàn)代碼
//2.1添加數(shù)據(jù)
[self.dataArray addObject:item];
//2.2刷新
[self.tableView reloadData];
};
}
30.UINavigationController(頂部導(dǎo)航條控制器)
1.代碼創(chuàng)建并設(shè)UINavigationController為window的跟控制器
在AppDelegate的didFinishLaunchingWithOptions方法中
1.創(chuàng)建window
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
2.創(chuàng)建UINavigationController并設(shè)置根控制器
UIViewController *vc = [[UIViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
3.顯示window
[self.window makeKeyAndVisible];
//注意:需要將info.plist中的storyboard選項(xiàng)刪除
2.控制器之間的跳轉(zhuǎn)(先放的控制器在棧底,只能從頂部往下移除控制器)
1.push跳轉(zhuǎn)(往棧中放一個(gè)控制器)
UIViewController *vc = [UIViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
2.pop跳轉(zhuǎn)
1.跳轉(zhuǎn)到上一個(gè)控制器(移除頂部的控制器)
[self.navigationController popViewControllerAnimated:YES];
2.跳轉(zhuǎn)到根控制器(移除根控制器以外所有控制器)
[self.navigationController popToRootViewControllerAnimated:YES];
3.跳轉(zhuǎn)到指定的控制器(移除指定控制器上面的控制器)
[self.navigationController popToViewController:self.navigationController.childViewControllers[0] animated:YES];
3.在storyboard中操作以上設(shè)置
1.創(chuàng)建UIViewController
1.拖一個(gè)UINavigationController視圖
2.拖一個(gè)UIViewController視圖
3.將UIViewController設(shè)置為UINavigationController視圖的rootViewController
按command+左鍵->拖線->選rootViewController
//注意:如果沒(méi)設(shè)置view顏色,會(huì)顯示為黑色
2.控制器的跳轉(zhuǎn)
1.自動(dòng)跳轉(zhuǎn)
從原控制器的控件(能監(jiān)聽(tīng)事件)中拖線到目標(biāo)控制器->選show//push已廢棄
2.手動(dòng)跳轉(zhuǎn)
從原控制器(上面的黃點(diǎn))中拖線到目標(biāo)控制器->選show//push已廢棄
//返回只能用代碼
//注意:在storyboard中線不能交叉
4.設(shè)置導(dǎo)航條的內(nèi)容(哪個(gè)的導(dǎo)航條由哪個(gè)控制器設(shè)置)(在storyboard中找相對(duì)應(yīng)屬性)
1.設(shè)置導(dǎo)航條標(biāo)題
self.navigationItem.title =@"標(biāo)題";
2.設(shè)置導(dǎo)航條視圖
self.navigationItem.titleView = [[UIView alloc]init];
3.設(shè)置導(dǎo)航條右邊視圖(左邊同理)
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"right"style:0target:selfaction:@selector(rightClick)];
4.在導(dǎo)航條中設(shè)置自定義的控件
UIButton *btn = [[UIButton alloc]init];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
31.控制器之間數(shù)據(jù)傳遞
1.正向傳遞數(shù)據(jù)
在prepareForSegue方法中,先獲取跳轉(zhuǎn)時(shí)的segue,再獲得目標(biāo)控制器,再給目標(biāo)控制器的屬性賦值
//在storyboard中,不管是自動(dòng)跳轉(zhuǎn)還是手動(dòng)跳轉(zhuǎn),都會(huì)調(diào)用這個(gè)方法
//用代碼push不會(huì)調(diào)用
2.prepareForSegue底層實(shí)現(xiàn):
1.創(chuàng)建segue對(duì)象
2.將self賦值給segue的sourceViewController(源控制器)
3.創(chuàng)建目標(biāo)控制器,并賦值給segue的destinationViewController
4.傳遞參數(shù)
5.從源控制器push到目標(biāo)控制器
3.逆向傳遞數(shù)據(jù)
1.導(dǎo)入頭文件實(shí)現(xiàn)
//耦合性太強(qiáng)
2.使用代理
1.目標(biāo)控制器
1.聲明協(xié)議
2.聲明代理屬性(遵守協(xié)議)
3.調(diào)用代理方法//在返回上一層控制器前代用
2.源控制器
1.遵守協(xié)議
2.實(shí)現(xiàn)協(xié)議中的方法
3.設(shè)置self為目標(biāo)控制器代理//在prepareForSegue中
3.使用block
1.目標(biāo)控制器
1.聲明block屬性//一般使用typedef起別名
2.執(zhí)行block//傳遞參數(shù),在返回上層控制器之前執(zhí)行
2.源控制器
1.獲得目標(biāo)控制器//在prepareForSegue中
2.給目標(biāo)控制器的block賦值//即要執(zhí)行的代碼塊
4.通知
1.目標(biāo)控制器
發(fā)出通知到通知中心,并將數(shù)據(jù)打包成字典給userInfo//postNotification
2.源控制器
監(jiān)聽(tīng)通知//注意:在dealloc中要移除監(jiān)聽(tīng)
32.UITabBarController(底部導(dǎo)航條控制器)
1.代碼創(chuàng)建
1.創(chuàng)建window
self.window = [[UIWindow alloc]init];
2.創(chuàng)建UITabBarController
UITabBarController *tabVC =[[UITabBarController alloc] init];
3.添加子控件
UIViewController *vc1 = [[UIViewController alloc] init];
[tabVC addChildViewController:vc1];
//添加多少個(gè)子控制器,則底部導(dǎo)航條平分為多少份,并創(chuàng)建按鈕(默認(rèn)無(wú)文字無(wú)顏色)
UIViewController *vc2 = [[UIViewController alloc] init];
[tabVC addChildViewController:vc2];
4.顯示window
[self.window makeKeyAndVisible];
2.在storyboard中
1.拖一個(gè)UITabBarController視圖
2.拖子控制器UIViewController
3.從UITabBarController拖線到UIViewController,選view controllers
4.重復(fù)第3步,可添加多個(gè)子控制器
3.設(shè)置導(dǎo)航條內(nèi)容(哪個(gè)的導(dǎo)航條由哪個(gè)控制器設(shè)置)(在storyboard中找相對(duì)應(yīng)屬性)
1.設(shè)置顯示文字
self.tabBarItem.title =@"消息";
2.設(shè)置右上角紅色信息
self.tabBarItem.badgeValue =@"10";
3.設(shè)置顯示圖片
self.tabBarItem.image = [UIImage imageNamed:@"image"];
3.modal跳轉(zhuǎn)控制器
1.代碼跳轉(zhuǎn)
1.跳轉(zhuǎn)到指定控制器
UIViewController *vc = [UIViewController alloc] init];
[selfpresentViewController:vc animated:YEScompletion:^{ }];
2.返回上一層控制器
[selfdismissViewControllerAnimated:YEScompletion:^{ }];
2.在storyboard中
從源控制器(控件)拖線到目標(biāo)控制器->選Present Modally//modal已廢棄
//返回只能用代碼實(shí)現(xiàn)
33.dismissed的原理:它本身就是一個(gè)消息機(jī)制首先會(huì)判斷它有沒(méi)有彈出控制器,假如有的話調(diào)用dismiss就會(huì)銷(xiāo)毀彈出的控制假如沒(méi)有的話就會(huì)銷(xiāo)毀自己.
34.http:其0.9的版本和1.1的版本最大的區(qū)別是1.1可以持續(xù)鏈接他有兩個(gè)操作一個(gè)是請(qǐng)求還有一個(gè)就是響應(yīng)
35.get和post的區(qū)別
post發(fā)給服務(wù)器的參數(shù)放在請(qǐng)求體中其傳遞的數(shù)量沒(méi)有限制它的安全性比get高一般包含敏感信息的文件都用post文件傳輸
get一般它的url長(zhǎng)度不能超過(guò)1kb它傳輸?shù)臄?shù)據(jù)的大小一般都比較小
36.發(fā)送http請(qǐng)求的方案: nsurlConnection和nsurlsessioncfnetwork這三種
一般用第三方框架:AFNeWorking
37.將data轉(zhuǎn)為字符串[[NSString alloc]initWithData:date encoding:NSUTF8StringEncoding];這種方式可以
38.http的
NSURLConnection的get請(qǐng)求的方式已被棄用
/*
//路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//請(qǐng)求對(duì)象
NSURLRequest *quest = [NSURLRequest requestWithURL:url];
//異步請(qǐng)求的方式
[NSURLConnectionsendAsynchronousRequest:quest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSLog(@"%@ ",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
//同步請(qǐng)求的方式
NSURLResponse *response = [[NSURLResponse alloc]init];
NSData *date= [ NSURLConnectionsendSynchronousRequest:quest returningResponse:&response error:nil];
NSLog(@"%@ ",[[NSString alloc]initWithData:date encoding:NSUTF8StringEncoding]);
//代理的方式
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//請(qǐng)求對(duì)象
NSURLRequest *quest = [NSURLRequest requestWithURL:url];
NSURLConnection *connect =[[NSURLConnectionalloc ]initWithRequest:quest delegate:self];
當(dāng)有startImmediately且為NO的時(shí)候就要自動(dòng)開(kāi)啟
[connect start];
*/
post的請(qǐng)求方式:
/*//1.確定請(qǐng)求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520&pwd=520it&type=JSON"];
//2.創(chuàng)建請(qǐng)求對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.創(chuàng)建會(huì)話對(duì)象
NSURLSession *session = [NSURLSession sharedSession];
//4.創(chuàng)建task
第一個(gè)參數(shù):請(qǐng)求對(duì)象
第二個(gè)參數(shù):completionHandler完成(成功|失敗)后的回調(diào)
data:響應(yīng)體
response:響應(yīng)頭信息
error:錯(cuò)誤信息
//注意!!!completionHandler是在子線程中執(zhí)行的
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//6.解析數(shù)據(jù)
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSLog(@"%@",[NSThread currentThread]);
}];
//5.執(zhí)行Task
[dataTask resume];*/
39.downloadtask下載任務(wù):
1.傳入url
2.新建請(qǐng)求對(duì)象
這里要設(shè)置假如程序退出了,下載從上次的地方接著開(kāi)始下這時(shí)候就要用可變的請(qǐng)求去調(diào)用setValue的方法
3.創(chuàng)建session對(duì)象創(chuàng)建下載任務(wù)對(duì)象使用代理(遵守代理協(xié)議);
4.一定要resume恢復(fù)其操作;
調(diào)用方法: a.接受響應(yīng)獲取文件的總大小
新建一個(gè)輸出流對(duì)象調(diào)用打開(kāi)的方法用一個(gè)屬性去接收
b.接收數(shù)據(jù)可以拿到當(dāng)前的傳輸數(shù)據(jù)的大小總共傳輸了大小用一個(gè)屬性去保存每次傳輸?shù)拇笮≡倜看渭由厦看蝹鬏數(shù)臄?shù)據(jù)的大小設(shè)置存儲(chǔ)路徑將數(shù)據(jù)一點(diǎn)點(diǎn)的加進(jìn)磁盤(pán)內(nèi)用輸出流對(duì)象調(diào)用將數(shù)據(jù)寫(xiě)入磁盤(pán)內(nèi)
并在這里調(diào)用刷新UI的方法在主線程中
c.任務(wù)完成或者請(qǐng)求出錯(cuò)
將輸出流對(duì)象調(diào)用關(guān)閉的方法并將輸出流對(duì)象設(shè)置成nil
[[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:nil];本地文件的寫(xiě)入移動(dòng).
40.AFNetWorking的應(yīng)用;
發(fā)送請(qǐng)求: get請(qǐng)求創(chuàng)建一個(gè)會(huì)話創(chuàng)建一個(gè)字典調(diào)用get方法
//NSString *url = @"http://120.25.226.186:32812/login";
AFHTTPSessionManager *http = [AFHTTPSessionManager manager];
NSDictionary *dic =@{
@"username":@"520it",
@"pwd":@"520it",
};
[http GET:@"http://120.25.226.186:32812/login"parameters:dic progress:nilsuccess:^(NSURLSessionDataTask *_Nonnulltask,id_NullableresponseObject) {
NSLog(@"請(qǐng)求成功");
NSLog(@"%@ ------%@",[responseObject class],responseObject);
} failure:^(NSURLSessionDataTask *_Nullabletask, NSError *_Nonnullerror) {
NSLog(@"請(qǐng)求失敗");
}];
post請(qǐng)求創(chuàng)建一個(gè)會(huì)話創(chuàng)建一個(gè)字典調(diào)用post方法跟get方法一樣;
2.文件上傳upload
//1.創(chuàng)建會(huì)話管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.發(fā)送請(qǐng)求上傳文件
/*
第一個(gè)參數(shù):請(qǐng)求路徑(NSString)
第二個(gè)參數(shù):非文件參數(shù)
第三個(gè)參數(shù):constructingBodyWithBlock拼接數(shù)據(jù)(告訴AFN要上傳的數(shù)據(jù)是哪些)
第四個(gè)參數(shù):progress進(jìn)度回調(diào)
第五個(gè)參數(shù):success成功回調(diào)
responseObject:響應(yīng)體
第六個(gè)參數(shù):failure失敗的回調(diào)
*/
[manager POST:@"http://120.25.226.186:32812/upload"parameters:nilconstructingBodyWithBlock:^(id_NonnullformData) {
//拼接數(shù)據(jù)
/*
第一個(gè)參數(shù):文件的路徑(NSURL)
第二個(gè)參數(shù):參數(shù)名~file
第三個(gè)參數(shù):該文件上傳到服務(wù)器以什么名稱(chēng)來(lái)保存
第四個(gè)參數(shù):文件的二進(jìn)制數(shù)據(jù)類(lèi)型
*/
NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/Snip20160409_148.png"];
//[formData appendPartWithFileURL:url name:@"file" fileName:@"abc.png" mimeType:@"image/png" error:nil];
[formData appendPartWithFileURL:url name:@"file"error:nil];
} progress:^(NSProgress *_NonnulluploadProgress) {
NSLog(@"%f",1.0* uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask *_Nonnulltask,id_NullableresponseObject) {
NSLog(@"success--%@",responseObject);
} failure:^(NSURLSessionDataTask *_Nullabletask, NSError *_Nonnullerror) {
NSLog(@"failure -- %@",error);
}];
41.加密過(guò)程:機(jī)密的一些最基本的操作
NSString *key =@"abc";
NSString *string =@"520it";
//AES - ECB加密
/*
第一個(gè)參數(shù):要加密的明文(字符串)
第二個(gè)參數(shù):共享密鑰
第三個(gè)參數(shù):nil (初始向量)
*/
NSLog(@"AES - ECB加密:%@",[[EncryptionTools sharedEncryptionTools] encryptString:string keyString:key iv:nil]);
//FqRpCOQG9IL2QrKBHhM+fA==
NSLog(@"AES - ECB解密:%@",[[EncryptionTools sharedEncryptionTools] decryptString:@"FqRpCOQG9IL2QrKBHhM+fA=="keyString:key iv:nil]);
//AES -CBC
uint8_t iv[8] ={1,2,3,4,5,6,7,8};
NSData *data = [NSData dataWithBytes:iv length:sizeof(iv)];
NSLog(@"AES - CBC加密:%@",[[EncryptionTools sharedEncryptionTools] encryptString:string keyString:key iv:data]);
//$ echo -n "520it" |openssl enc -aes-128-cbc -K 616263 -nosalt -iv 0102030405060708 |base64
NSLog(@"AES - CBC解密:%@",[[EncryptionTools sharedEncryptionTools] decryptString:@"Kd9MN/rNEI40hdLhayPbUw=="keyString:key iv:data]);
//DES - ECB
//1.需要修改加密方式為kCCAlgorithmDES
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
NSLog(@"DES - ECB加密:%@",[[EncryptionTools sharedEncryptionTools] encryptString:string keyString:key iv:nil]);
NSLog(@"DES - ECB解密:%@",[[EncryptionTools sharedEncryptionTools] decryptString:@"VqYjXo2ZlU4="keyString:key iv:nil]);
42.基礎(chǔ)動(dòng)畫(huà)和核心動(dòng)畫(huà)
CAPropertyAnimation
是CAAnimation的子類(lèi)斥黑,也是個(gè)抽象類(lèi)揖盘,要想創(chuàng)建動(dòng)畫(huà)對(duì)象,應(yīng)該使用它的兩個(gè)子類(lèi):CABasicAnimation和CAKeyframeAnimation
屬性解析:
keyPath:通過(guò)指定CALayer的一個(gè)屬性名稱(chēng)為keyPath(NSString類(lèi)型)锌奴,并且對(duì)CALayer的這個(gè)屬性的值進(jìn)行修改兽狭,達(dá)到相應(yīng)的動(dòng)畫(huà)效果。比如鹿蜀,指定@”position”為keyPath箕慧,就修改CALayer的position屬性的值,以達(dá)到平移的動(dòng)畫(huà)效果
屬性解析:(紅色代表來(lái)自CAMediaTiming協(xié)議的屬性)
duration:動(dòng)畫(huà)的持續(xù)時(shí)間
repeatCount:動(dòng)畫(huà)的重復(fù)次數(shù)
repeatDuration:動(dòng)畫(huà)的重復(fù)時(shí)間
removedOnCompletion:默認(rèn)為YES茴恰,代表動(dòng)畫(huà)執(zhí)行完畢后就從圖層上移除颠焦,圖形會(huì)恢復(fù)到動(dòng)畫(huà)執(zhí)行前的狀態(tài)。如果想讓圖層保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)往枣,那就設(shè)置為NO伐庭,不過(guò)還要設(shè)置fillMode為kCAFillModeForwards
fillMode:決定當(dāng)前對(duì)象在非active時(shí)間段的行為.比如動(dòng)畫(huà)開(kāi)始之前,動(dòng)畫(huà)結(jié)束之后
beginTime:可以用來(lái)設(shè)置動(dòng)畫(huà)延遲執(zhí)行時(shí)間,若想延遲2s分冈,就設(shè)置為CACurrentMediaTime()+2圾另,CACurrentMediaTime()為圖層的當(dāng)前時(shí)間
timingFunction:速度控制函數(shù),控制動(dòng)畫(huà)運(yùn)行的節(jié)奏
delegate:動(dòng)畫(huà)代理
fromValue:keyPath相應(yīng)屬性的初始值
toValue:keyPath相應(yīng)屬性的結(jié)束值
隨著動(dòng)畫(huà)的進(jìn)行雕沉,在長(zhǎng)度為duration的持續(xù)時(shí)間內(nèi)集乔,keyPath相應(yīng)屬性的值從fromValue漸漸地變?yōu)閠oValue
如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在動(dòng)畫(huà)執(zhí)行完畢后蘑秽,圖層會(huì)保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)饺著。但在實(shí)質(zhì)上箫攀,圖層的屬性值還是動(dòng)畫(huà)執(zhí)行前的初始值,并沒(méi)有真正被改變幼衰。比如靴跛,CALayer的position初始值為(0,0),CABasicAnimation的fromValue為(10,10)渡嚣,toValue為(100,100)梢睛,雖然動(dòng)畫(huà)執(zhí)行完畢后圖層保持在(100,100)這個(gè)位置,實(shí)質(zhì)上圖層的position還是為(0,0)
CAKeyframeAnimation是CApropertyAnimation的子類(lèi)识椰,跟CABasicAnimation的區(qū)別是:CABasicAnimation只能從一個(gè)數(shù)值(fromValue)變到另一個(gè)數(shù)值(toValue)绝葡,而CAKeyframeAnimation會(huì)使用一個(gè)NSArray保存這些數(shù)值
屬性解析:
values:就是上述的NSArray對(duì)象。里面的元素稱(chēng)為”關(guān)鍵幀”(keyframe)腹鹉。動(dòng)畫(huà)對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi)藏畅,依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀
path:可以設(shè)置一個(gè)CGPathRef\CGMutablePathRef,讓層跟著路徑移動(dòng)。path只對(duì)CALayer的anchorPoint和position起作用功咒。如果你設(shè)置了path愉阎,那么values將被忽略
keyTimes:可以為對(duì)應(yīng)的關(guān)鍵幀指定對(duì)應(yīng)的時(shí)間點(diǎn),其取值范圍為0到1.0,keyTimes中的每一個(gè)時(shí)間值都對(duì)應(yīng)values中的每一幀.當(dāng)keyTimes沒(méi)有設(shè)置的時(shí)候,各個(gè)關(guān)鍵幀的時(shí)間是平分的
CABasicAnimation可看做是最多只有2個(gè)關(guān)鍵幀的CAKeyframeAnimation
運(yùn)用:
CAAnimationGroup
CAAnimation的子類(lèi),可以保存一組動(dòng)畫(huà)對(duì)象力奋,將CAAnimationGroup對(duì)象加入層后榜旦,組中所有動(dòng)畫(huà)對(duì)象可以同時(shí)并發(fā)運(yùn)行
animations:用來(lái)保存一組動(dòng)畫(huà)對(duì)象的NSArray
默認(rèn)情況下,一組動(dòng)畫(huà)對(duì)象是同時(shí)運(yùn)行的景殷,也可以通過(guò)設(shè)置動(dòng)畫(huà)對(duì)象的beginTime屬性來(lái)更改動(dòng)畫(huà)的開(kāi)始時(shí)間
組動(dòng)畫(huà)
CATransition是CAAnimation的子類(lèi)溅呢,用于做轉(zhuǎn)場(chǎng)動(dòng)畫(huà),能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫(huà)效果猿挚。iOS比Mac OS X的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)效果少一點(diǎn)
UINavigationController就是通過(guò)CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫(huà)效果
type:動(dòng)畫(huà)過(guò)渡類(lèi)型
subtype:動(dòng)畫(huà)過(guò)渡方向
startProgress:動(dòng)畫(huà)起點(diǎn)(在整體動(dòng)畫(huà)的百分比)
endProgress:動(dòng)畫(huà)終點(diǎn)(在整體動(dòng)畫(huà)的百分比)
轉(zhuǎn)場(chǎng)動(dòng)畫(huà)過(guò)渡效果
運(yùn)用:
雨滴效果
補(bǔ)充:
一:CAAnimation——?jiǎng)赢?huà)代理方法
1.CAAnimation在分類(lèi)中定義了代理方法,是給NSObject添加的分類(lèi),所以任何對(duì)象,成為CAAnimation的代理都可以
@interfaceNSObject (CAAnimationDelegate)
/* Called when the animation begins its active duration. */
動(dòng)畫(huà)開(kāi)始的時(shí)候調(diào)用:-(void)animationDidStart:(CAAnimation*)anim;
動(dòng)畫(huà)停止的時(shí)候調(diào)用:-(void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag;
@end
二:CALayer上動(dòng)畫(huà)的暫停和恢復(fù)
pragma mark暫停CALayer的動(dòng)畫(huà)
-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
讓CALayer的時(shí)間停止走動(dòng):layer.speed =0.0;
讓CALayer的時(shí)間停留在pausedTime這個(gè)時(shí)刻:layer.timeOffset = pausedTime;
}
三:CALayer上動(dòng)畫(huà)的恢復(fù)
pragma mark恢復(fù)CALayer的動(dòng)畫(huà)
-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = layer.timeOffset;
1.讓CALayer的時(shí)間繼續(xù)行走:layer.speed =1.0;
2.取消上次記錄的停留時(shí)刻:layer.timeOffset =0.0;
3.取消上次設(shè)置的時(shí)間:layer.beginTime =0.0;
4.計(jì)算暫停的時(shí)間(這里也可以用CACurrentMediaTime()-pausedTime)
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime()fromLayer:nil] - pausedTime;
5.設(shè)置相對(duì)于父坐標(biāo)系的開(kāi)始時(shí)間(往后退timeSincePause):layer.beginTime = timeSincePause;
}
二咐旧、UIView動(dòng)畫(huà)
UIKit直接將動(dòng)畫(huà)集成到UIView類(lèi)中,當(dāng)內(nèi)部的一些屬性發(fā)生改變時(shí)亭饵,UIView將為這些改變提供動(dòng)畫(huà)支持
執(zhí)行動(dòng)畫(huà)所需要的工作由UIView類(lèi)自動(dòng)完成休偶,但仍要在希望執(zhí)行動(dòng)畫(huà)時(shí)通知視圖,為此需要將改變屬性的代碼放在[UIView beginAnimations:nilcontext:nil]和[UIView commitAnimations]之間
常見(jiàn)方法解析:
+ (void)setAnimationDelegate:(id)delegate
設(shè)置動(dòng)畫(huà)代理對(duì)象辜羊,當(dāng)動(dòng)畫(huà)開(kāi)始或者結(jié)束時(shí)會(huì)發(fā)消息給代理對(duì)象
+ (void)setAnimationWillStartSelector:(SEL)selector
當(dāng)動(dòng)畫(huà)即將開(kāi)始時(shí)踏兜,執(zhí)行delegate對(duì)象的selector,并且把beginAnimations:context:中傳入的參數(shù)傳進(jìn)selector
+ (void)setAnimationDidStopSelector:(SEL)selector
當(dāng)動(dòng)畫(huà)結(jié)束時(shí)八秃,執(zhí)行delegate對(duì)象的selector碱妆,并且把beginAnimations:context:中傳入的參數(shù)傳進(jìn)selector
+ (void)setAnimationDuration:(NSTimeInterval)duration
動(dòng)畫(huà)的持續(xù)時(shí)間,秒為單位
+ (void)setAnimationDelay:(NSTimeInterval)delay
動(dòng)畫(huà)延遲delay秒后再開(kāi)始
+ (void)setAnimationStartDate:(NSDate *)startDate
動(dòng)畫(huà)的開(kāi)始時(shí)間昔驱,默認(rèn)為now
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve
動(dòng)畫(huà)的節(jié)奏控制,具體看下面的”備注”
+ (void)setAnimationRepeatCount:(float)repeatCount
動(dòng)畫(huà)的重復(fù)次數(shù)
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses
如果設(shè)置為YES,代表動(dòng)畫(huà)每次重復(fù)執(zhí)行的效果會(huì)跟上一次相反
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition
forView:(UIView *)view cache:(BOOL)cache
設(shè)置視圖view的過(guò)渡效果, transition指定過(guò)渡類(lèi)型, cache設(shè)置YES代表使用視圖緩存疹尾,性能較好
三、Block動(dòng)畫(huà)
Block
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOLfinished))completion
###參數(shù)解析:
duration:動(dòng)畫(huà)的持續(xù)時(shí)間
delay:動(dòng)畫(huà)延遲delay秒后開(kāi)始
options:動(dòng)畫(huà)的節(jié)奏控制
animations:將改變視圖屬性的代碼放在這個(gè)block中
completion:動(dòng)畫(huà)結(jié)束后,會(huì)自動(dòng)調(diào)用這個(gè)block
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOLfinished))completion
###參數(shù)解析:
duration:動(dòng)畫(huà)的持續(xù)時(shí)間
view:需要進(jìn)行轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的視圖
options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類(lèi)型
animations:將改變視圖屬性的代碼放在這個(gè)block中
completion:動(dòng)畫(huà)結(jié)束后纳本,會(huì)自動(dòng)調(diào)用這個(gè)block
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void(^)(BOOLfinished))completion
###方法調(diào)用完畢后窍蓝,相當(dāng)于執(zhí)行了下面兩句代碼:
//添加toView到父視圖
[fromView.superview addSubview:toView];
//把fromView從父視圖中移除
[fromView.superview removeFromSuperview];
###參數(shù)解析:
duration:動(dòng)畫(huà)的持續(xù)時(shí)間
options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類(lèi)型
animations:將改變視圖屬性的代碼放在這個(gè)block中
completion:動(dòng)畫(huà)UIImageView的幀動(dòng)畫(huà)后,會(huì)自動(dòng)調(diào)用這個(gè)block
UIImageView的幀動(dòng)畫(huà)
UIImageView可以讓一系列的圖片在特定的時(shí)間內(nèi)按順序顯示
###相關(guān)屬性解析:
animationImages:要顯示的圖片(一個(gè)裝著UIImage的NSArray)
animationDuration:完整地顯示一次animationImages中的所有圖片所需的時(shí)間
animationRepeatCount:動(dòng)畫(huà)的執(zhí)行次數(shù)(默認(rèn)為0繁成,代表無(wú)限循環(huán))
###相關(guān)方法解析:
-(void)startAnimating;開(kāi)始動(dòng)畫(huà)
-(void)stopAnimating;停止動(dòng)畫(huà)
-(BOOL)isAnimating;是否正在運(yùn)行動(dòng)畫(huà)
UIActivityIndicatorView
###是一個(gè)旋轉(zhuǎn)進(jìn)度輪吓笙,可以用來(lái)告知用戶有一個(gè)操作正在進(jìn)行中,一般用initWithActivityIndicatorStyle初始化
###UIActivityIndicatorViewStyle有3個(gè)值可供選擇:
UIActivityIndicatorViewStyleWhiteLarge//大型白色指示器
UIActivityIndicatorViewStyleWhite//標(biāo)準(zhǔn)尺寸白色指示器
UIActivityIndicatorViewStyleGray//灰色指示器巾腕,用于白色背景