AFN的詳細(xì)使用

1.在開發(fā)的時(shí)候可以創(chuàng)建一個(gè)工具類,繼承自我們的AFN中的請求管理者,再控制器中真正發(fā)請求的代碼使用自己封裝的工具類。

2.這樣做的優(yōu)點(diǎn)是以后如果修改了底層依賴的框架,那么我們修改這個(gè)工具類就可以了,而不用再一個(gè)一個(gè)的去修改。

3.該工具類一般提供一個(gè)單例方法,在該方法中會(huì)設(shè)置一個(gè)基本的請求路徑。

4.該方法通常還會(huì)提供對GET或POST請求的封裝。

5.在外面的時(shí)候通過該工具類來發(fā)送請求

6.單例方法:

+ (instancetype)shareNetworkTools

{

static XMGNetworkTools *instance;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

//注意: BaseURL中一定要以/結(jié)尾

instance = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"http://120.25.226.186:32812/"]];

});

return instance;

}


2.AFN文件上傳


1.文件上傳拼接數(shù)據(jù)的第一種方式

[formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"];

2.文件上傳拼接數(shù)據(jù)的第二種方式

[formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"xx.png" mimeType:@"application/octet-stream" error:nil];

3.文件上傳拼接數(shù)據(jù)的第三種方式

[formData appendPartWithFileURL:fileUrl name:@"file" error:nil];

4.【注】在資料中已經(jīng)提供了一個(gè)用于文件上傳的分類。

/*文件上傳相關(guān)的代碼如下*/

-(void)upload

{

//1.創(chuàng)建一個(gè)請求管理者

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.發(fā)送POST請求上傳數(shù)據(jù)

/*

第一個(gè)參數(shù):請求路徑:NSString類型

第二個(gè)參數(shù):要上傳的非文件參數(shù)

第三個(gè)參數(shù):block回調(diào)

在該回調(diào)中,需要利用formData拼接即將上傳的二進(jìn)制數(shù)據(jù)

第三個(gè)參數(shù):上傳成功的block回調(diào)

task:dataTask(任務(wù))

responseObject:服務(wù)器返回的數(shù)據(jù)

第四個(gè)參數(shù):上傳失敗的block回調(diào)

error:錯(cuò)誤信息,如果上傳文件失敗,那么error里面包含了錯(cuò)誤的描述信息

*/

NSDictionary *dict = @{

@"username":@"wenidngding"

};

[manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id_Nonnull formData) {

//把本地的圖片轉(zhuǎn)換為NSData類型的數(shù)據(jù)

UIImage *image = [UIImage imageNamed:@"123"];

NSData *data = UIImagePNGRepresentation(image);

/*

//拼接二進(jìn)制文件數(shù)據(jù)

第一個(gè)參數(shù):要上傳的文件的二進(jìn)制數(shù)據(jù)

第二個(gè)參數(shù):服務(wù)器接口規(guī)定的名稱

第三個(gè)參數(shù):這個(gè)參數(shù)上傳到服務(wù)器之后用什么名字來進(jìn)行保存

第四個(gè)參數(shù):上傳文件的MIMEType類型

*/

[formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"];

} success:^(NSURLSessionDataTask * _Nonnull task, id_Nonnull responseObject) {

NSLog(@"請求成功---%@",responseObject);

} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {

NSLog(@"請求失敗--%@",error);

}];

}

-(void)upload2

{

NSLog(@"%s",__func__);

//1.創(chuàng)建一個(gè)請求管理者

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.發(fā)送POST請求上傳數(shù)據(jù)

/*

第一個(gè)參數(shù):請求路徑:NSString類型

第二個(gè)參數(shù):要上傳的非文件參數(shù)

第三個(gè)參數(shù):block回調(diào)

在該回調(diào)中,需要利用formData拼接即將上傳的二進(jìn)制數(shù)據(jù)

第三個(gè)參數(shù):上傳成功的block回調(diào)

task:dataTask(任務(wù))

responseObject:服務(wù)器返回的數(shù)據(jù)

第四個(gè)參數(shù):上傳失敗的block回調(diào)

error:錯(cuò)誤信息,如果上傳文件失敗,那么error里面包含了錯(cuò)誤的描述信息

*/

NSDictionary *dict = @{

@"username":@"wenidngding"

};

[manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id_Nonnull formData) {

//本地文件的url

NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/文頂頂/Desktop/KF[WTI`AQ3T`A@3R(B96D89.gif"];

/*

//拼接二進(jìn)制文件數(shù)據(jù)

第一個(gè)參數(shù):要上傳文件的url路徑

第二個(gè)參數(shù):服務(wù)器要求的參數(shù)名稱

第三個(gè)參數(shù):這個(gè)文件上傳到服務(wù)器之后叫什么名稱

第四個(gè)參數(shù):文件的mimetype類型

第五個(gè)參數(shù):錯(cuò)誤信息

*/

//[formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"xx.png" mimeType:@"application/octet-stream" error:nil];

//另外一種上傳文件的方式

/*

說明:該方法和上面的方法等價(jià),不過該方法更加簡單其內(nèi)部會(huì)自動(dòng)的的根據(jù)url路徑確定文件保存名稱,并通過內(nèi)部方法獲取上傳文件的mimetype類型

*/

[formData appendPartWithFileURL:fileUrl name:@"file" error:nil];

} success:^(NSURLSessionDataTask * _Nonnull task, id_Nonnull responseObject) {

NSLog(@"請求成功---%@",responseObject);

} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {

NSLog(@"請求失敗--%@",error);

}];

}

```

###3.使用AFN進(jìn)行序列化處理

```objc

/*

1.AFN它內(nèi)部默認(rèn)把服務(wù)器響應(yīng)的數(shù)據(jù)當(dāng)做json來進(jìn)行解析,所以如果服務(wù)器返回給我的不是JSON數(shù)據(jù)那么請求報(bào)錯(cuò),這個(gè)時(shí)候需要設(shè)置AFN對響應(yīng)信息的解析方式。AFN提供了三種解析響應(yīng)信息的方式,分別是:

1)AFXMLParserResponseSerializer----XML

2) AFHTTPResponseSerializer---------默認(rèn)二進(jìn)制響應(yīng)數(shù)據(jù)

3)AFJSONResponseSerializer---------JSON

2.還有一種情況就是服務(wù)器返回給我們的數(shù)據(jù)格式不太一致(開發(fā)者工具Content-Type:text/xml),那么這種情況也有可能請求不成功。解決方法:

1)直接在源代碼中修改,添加相應(yīng)的Content-Type

2)拿到這個(gè)屬性,添加到它的集合中

3.相關(guān)代碼

-(void)srializer

{

//1.創(chuàng)建請求管理者,內(nèi)部基于NSURLSession

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

/*知識(shí)點(diǎn)1:設(shè)置AFN采用什么樣的方式來解析服務(wù)器返回的數(shù)據(jù)*/

//如果返回的是XML,那么告訴AFN,響應(yīng)的時(shí)候使用XML的方式解析

manager.responseSerializer = [AFXMLParserResponseSerializer serializer];

//如果返回的就是二進(jìn)制數(shù)據(jù),那么采用默認(rèn)二進(jìn)制的方式來解析數(shù)據(jù)

//manager.responseSerializer = [AFHTTPResponseSerializer serializer];

//采用JSON的方式來解析數(shù)據(jù)

//manager.responseSerializer = [AFJSONResponseSerializer serializer];

/*知識(shí)點(diǎn)2:告訴AFN服務(wù)器返回的數(shù)據(jù)內(nèi)容是什么類型的Content-Type*/

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/xml"];

//2.把所有的請求參數(shù)通過字典的方式來裝載,GET方法內(nèi)部會(huì)自動(dòng)把所有的鍵值對取出以&符號(hào)拼接并最后用?符號(hào)連接在請求路徑后面

NSDictionary *dict = @{

@"username":@"223",

@"pwd":@"ewr",

@"type":@"XML"

};

//3.發(fā)送GET請求

[manager GET:@"http://120.25.226.186:32812/login" parameters:dict success:^(NSURLSessionDataTask * _Nonnull task, id_Nonnull responseObject) {

//4.請求成功的回調(diào)block

NSLog(@"%@",[responseObject class]);

} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {

//5.請求失敗的回調(diào),可以打印error的值查看錯(cuò)誤信息

NSLog(@"%@",error);

}];

}

```

###4.使用AFN來檢測網(wǎng)絡(luò)狀態(tài)

```objc

/*

說明:可以使用AFN框架中的AFNetworkReachabilityManager來監(jiān)聽網(wǎng)絡(luò)狀態(tài)的改變,也可以利用蘋果提供的Reachability來監(jiān)聽。建議在開發(fā)中直接使用AFN框架處理。

*/

//使用AFN框架來檢測網(wǎng)絡(luò)狀態(tài)的改變

-(void)AFNReachability

{

//1.創(chuàng)建網(wǎng)絡(luò)監(jiān)聽管理者

AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];

//2.監(jiān)聽網(wǎng)絡(luò)狀態(tài)的改變

/*

AFNetworkReachabilityStatusUnknown=未知

AFNetworkReachabilityStatusNotReachable=沒有網(wǎng)絡(luò)

AFNetworkReachabilityStatusReachableViaWWAN = 3G

AFNetworkReachabilityStatusReachableViaWiFi = WIFI

*/

[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

switch (status) {

case AFNetworkReachabilityStatusUnknown:

NSLog(@"未知");

break;

case AFNetworkReachabilityStatusNotReachable:

NSLog(@"沒有網(wǎng)絡(luò)");

break;

case AFNetworkReachabilityStatusReachableViaWWAN:

NSLog(@"3G");

break;

case AFNetworkReachabilityStatusReachableViaWiFi:

NSLog(@"WIFI");

break;

default:

break;

}

}];

//3.開始監(jiān)聽

[manager startMonitoring];

}

------------------------------------------------------------

//使用蘋果提供的Reachability來檢測網(wǎng)絡(luò)狀態(tài),如果要持續(xù)監(jiān)聽網(wǎng)絡(luò)狀態(tài)的概念,需要結(jié)合通知一起使用。

//提供下載地址:https://developer.apple.com/library/ios/samplecode/Reachability/Reachability.zip

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

//1.注冊一個(gè)通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkChange) name:kReachabilityChangedNotification object:nil];

//2.拿到一個(gè)對象,然后調(diào)用開始監(jiān)聽方法

Reachability *r = [Reachability reachabilityForInternetConnection];

[r startNotifier];

//持有該對象,不要讓該對象釋放掉

self.r = r;

}

//當(dāng)控制器釋放的時(shí)候,移除通知的監(jiān)聽

-(void)dealloc

{

[[NSNotificationCenter defaultCenter] removeObserver:self];

}

-(void)networkChange

{

//獲取當(dāng)前網(wǎng)絡(luò)的狀態(tài)

if([Reachability reachabilityForLocalWiFi].currentReachabilityStatus != NotReachable)

{

NSLog(@"當(dāng)前網(wǎng)絡(luò)為WIFI");

}else if ([Reachability reachabilityForInternetConnection].currentReachabilityStatus != NotReachable)

{

NSLog(@"當(dāng)前網(wǎng)絡(luò)為手機(jī)自帶網(wǎng)絡(luò)");

}else

{

NSLog(@"當(dāng)前沒有網(wǎng)絡(luò)");

}

}

```

###5.數(shù)據(jù)安全

```objc

01攻城利器:Charles(公司中一般都使用該工具來抓包,并做網(wǎng)絡(luò)測試)

注意:Charles在使用中的亂碼問題,可以顯示包內(nèi)容,然后打開info.plist文件,找到j(luò)ava目錄下面的VMOptions,在后面添加一項(xiàng):-Dfile.encoding=UTF-8

02 MD5消息摘要算法是不可逆的。

03數(shù)據(jù)加密的方式和規(guī)范一般公司會(huì)有具體的規(guī)定,不必多花時(shí)間。

```

###6.HTTPS的基本使用

```objc

1.https簡單說明

HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標(biāo)的HTTP通道,簡單講是HTTP的安全版。

即HTTP下加入SSL層,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL。它是一個(gè)URI scheme(抽象標(biāo)識(shí)符體系),句法類同http:體系。用于安全的HTTP數(shù)據(jù)傳輸。

https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默認(rèn)端口及一個(gè)加密/身份驗(yàn)證層(在HTTP與TCP之間)。

2.HTTPS和HTTP的區(qū)別主要為以下四點(diǎn):

一、https協(xié)議需要到ca申請證書,一般免費(fèi)證書很少,需要交費(fèi)。

二、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。

三、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。

四、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。

3.對開發(fā)的影響。

3.1如果是自己使用NSURLSession來封裝網(wǎng)絡(luò)請求,涉及代碼如下。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

NSURLSessionDataTask *task =[session dataTaskWithURL:[NSURL URLWithString:@"https://www.apple.com"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

}];

[task resume];

}

/*

只要請求的地址是HTTPS的,就會(huì)調(diào)用這個(gè)代理方法

我們需要在該方法中告訴系統(tǒng),是否信任服務(wù)器返回的證書

Challenge:挑戰(zhàn)質(zhì)問(包含了受保護(hù)的區(qū)域)

protectionSpace :受保護(hù)區(qū)域

NSURLAuthenticationMethodServerTrust :證書的類型是服務(wù)器信任

了解:證書有好幾種,一種是被認(rèn)證過的一種是沒有被認(rèn)證過的,如果證書是被認(rèn)證過的,那么只需要信任一次就可以了,如果是沒有被認(rèn)證過的,那么每次都需要重新認(rèn)證

*/

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler

{

//NSLog(@"didReceiveChallenge %@", challenge.protectionSpace);

NSLog(@"調(diào)用了最外層");

// 1.判斷服務(wù)器返回的證書類型,是否是服務(wù)器信任

if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {

NSLog(@"調(diào)用了里面這一層是服務(wù)器信任的證書");

/*

NSURLSessionAuthChallengeUseCredential = 0,使用證書

NSURLSessionAuthChallengePerformDefaultHandling = 1,忽略證書(默認(rèn)的處理方式)

NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2,忽略書證,并取消這次請求

NSURLSessionAuthChallengeRejectProtectionSpace = 3,忽略當(dāng)前這一次,下一次再詢問

*/

//NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];

NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];

completionHandler(NSURLSessionAuthChallengeUseCredential , card);

}

}

3.2如果是使用AFN框架,那么我們不需要做任何額外的操作,AFN內(nèi)部已經(jīng)做了處理。

```

###7 WebView的基本使用

```objc

1概念性知識(shí)

01 webView是有缺點(diǎn)的,會(huì)導(dǎo)致內(nèi)存泄露,而且這個(gè)問題是它系統(tǒng)本身的問題。

02手機(jī)上面的safai其實(shí)就是用webView來實(shí)現(xiàn)的

03現(xiàn)在的開發(fā)并不完全是原生的開發(fā),而更加傾向于原生+Html5的方式

04 webView是OC代碼和html代碼之間進(jìn)行交互的橋梁

2代碼相關(guān)

/*A*網(wǎng)頁操控相關(guān)方法**/

[self.webView goBack];回退

[self.webView goForward];前進(jìn)

[self.webView reload];刷新

//設(shè)置是否能夠前進(jìn)和回退

self.goBackBtn.enabled = webView.canGoBack;

self.fowardBtn.enabled = webView.canGoForward;

/*B*常用的屬性設(shè)置**/

self.webView.scalesPageToFit = YES;設(shè)置網(wǎng)頁自動(dòng)適應(yīng)

self.webView.dataDetectorTypes = UIDataDetectorTypeAll;設(shè)置檢測網(wǎng)頁中的格式類型,all表示檢測所有類型包括超鏈接、電話號(hào)碼、地址等。

self.webView.scrollView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0);

/*C*相關(guān)代理方法**/

//每當(dāng)將加載請求的時(shí)候調(diào)用該方法,返回YES表示加載該請求,返回NO表示不加載該請求

//可以在該方法中攔截請求

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

{

return ![request.URL.absoluteString containsString:@"dushu"];

}

//開始加載網(wǎng)頁,不僅監(jiān)聽我們指定的請求,還會(huì)監(jiān)聽內(nèi)部發(fā)送的請求

-(void)webViewDidStartLoad:(UIWebView *)webView

//網(wǎng)頁加載完畢之后會(huì)調(diào)用該方法

-(void)webViewDidFinishLoad:(UIWebView *)webView

//網(wǎng)頁加載失敗調(diào)用該方法

-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error

/*D*其它知識(shí)點(diǎn)-加載本地資源**/

NSURL *url = [[NSBundle mainBundle] URLForResource:@"text.html" withExtension:nil];

[self.webView loadRequest:[NSURLRequest requestWithURL:url]];

```

####8 HTML

```objc

1.Html決定網(wǎng)頁的內(nèi)容,css決定網(wǎng)頁的樣式,js決定網(wǎng)頁的事件

2.html學(xué)習(xí)網(wǎng)站:http://www.w3school.com.cn

```

####9 OC和JS代碼的互調(diào)

```objc

01 OC調(diào)用JS的代碼

NSString *str = [self.webView stringByEvaluatingJavaScriptFromString:@"sum()"];

02 JS怎么調(diào)用OC的說明

新的需求:點(diǎn)擊按鈕的時(shí)候撥打電話

但是我在點(diǎn)擊按鈕的時(shí)候,用戶是不知道的,我們怎么能夠知道用戶點(diǎn)擊了網(wǎng)頁上面的一個(gè)按鈕,只能通過一個(gè)技巧,那就是自己搞一個(gè)特定的協(xié)議頭比如說xmg://,當(dāng)我攔截到你的網(wǎng)絡(luò)請求的時(shí)候,只需要判斷一下當(dāng)前的協(xié)議頭是不是這個(gè)就能判斷你現(xiàn)在是否是JS調(diào)用。

OC里面有通過字符串生成SEL類型的方法,所以當(dāng)拿到數(shù)據(jù)之后做下面的事情

1)截取方法的名稱

2)將截取出來的字符串轉(zhuǎn)換為SEL

3)利用performSelect方法來調(diào)用SEL

03涉及到的相關(guān)方法

[@"abc" hasPrefix:@"A"] //判斷字符串是否以一個(gè)固定的字符開頭,這里為A

//截串操作

- (NSString *)substringFromIndex:(NSUInteger)from;

//切割字符串,返回一個(gè)數(shù)組

- (NSArray *)componentsSeparatedByString:(NSString *)separator;

//替換操作

- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement

//把string包裝成SEL

SEL selector = NSSelectorFromString(sel);

04如何屏蔽警告

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

//-Warc-performSelector-leaks為唯一的警告標(biāo)識(shí)

[self performSelector:selector withObject:nil];

#pragma clang diagnostic pop

```

####9 NSInvocation的基本使用

```objc

//封裝invacation可以調(diào)用多個(gè)參數(shù)的方法

-(void)invacation

{

//1.創(chuàng)建一個(gè)MethodSignature,簽名中保存了方法的名稱,參數(shù)和返回值

//這個(gè)方法屬于誰,那么就用誰來進(jìn)行創(chuàng)建

//注意:簽名一般是用來設(shè)置參數(shù)和獲得返回值的,和方法的調(diào)用沒有太大的關(guān)系

NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(callWithNumber:andContext:withStatus:)];

/*注意不要寫錯(cuò)了方法名稱

//NSMethodSignature *signature = [ViewController methodSignatureForSelector:@selector(call)];

*/

//2.通過MethodSignature來創(chuàng)建一個(gè)NSInvocation

//NSInvocation中保存了方法所屬于的對象|方法名稱|參數(shù)|返回值等等

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

/*2.1設(shè)置invocation,來調(diào)用方法*/

invocation.target = self;

//invocation.selector = @selector(call);

//invocation.selector = @selector(callWithNumber:);

//invocation.selector = @selector(callWithNumber:andContext:);

invocation.selector = @selector(callWithNumber:andContext:withStatus:);

NSString *number = @"10086";

NSString *context = @"下課了";

NSString *status = @"睡覺的時(shí)候";

//注意:

//1.自定義的參數(shù)索引從2開始,0和1已經(jīng)被self and _cmd占用了

//2.方法簽名中保存的方法名稱必須和調(diào)用的名稱一致

[invocation setArgument:&number atIndex:2];

[invocation setArgument:&context atIndex:3];

[invocation setArgument:&status atIndex:4];

/*3.調(diào)用invok方法來執(zhí)行*/

[invocation invoke];

}

```

####10異常處理

```objc

01一般處理方式:

a.app異常閃退,那么捕獲crash信息,并記錄在本地沙盒中。

b.當(dāng)下次用戶重新打開app的時(shí)候,檢查沙盒中是否保存有上次捕獲到的crash信息。

c.如果有那么利用專門的接口發(fā)送給服務(wù)器,以求在后期版本中修復(fù)。

02如何拋出異常

//拋出異常的兩種方式

// @throw[NSException exceptionWithName:@"好大一個(gè)bug" reason:@"異常原因:我也不知道" userInfo:nil];

//方式二

NSString *info = [NSString stringWithFormat:@"%@方法找不到",NSStringFromSelector(aSelector)];

//下面這種方法是自動(dòng)拋出的

[NSException raise:@"這是一個(gè)異常" format:info,nil];

03如何捕獲異常

NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler);

void UncaughtExceptionHandler(NSException *exception) {

NSArray *arr = [exception callStackSymbols];//得到當(dāng)前調(diào)用棧信息

NSString *reason = [exception reason];//非常重要,就是崩潰的原因

NSString *name = [exception name];//異常類型

NSString *errorMsg = [NSString stringWithFormat:@"當(dāng)前調(diào)用棧的信息:%@\nCrash的原因:%@\n異常類型:%@\n",arr,reason,name];

//把該信息保存到本地沙盒,下次回傳給服務(wù)器。

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,034評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,337評(píng)論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,883評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評(píng)論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,114評(píng)論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,625評(píng)論 1 332
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,555評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,737評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評(píng)論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,973評(píng)論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評(píng)論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,343評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,699評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容