NSException是什么?
最熟悉的陌生人,這是我對NSException的概述,為什么這么說呢媒殉?其實很多開發(fā)者接觸到NSException的頻率非常頻繁,但很多人都不知道什么是NSException摔敛,不知道如何使用NSException廷蓉。下面從一張截圖開始講起NSException。
程序異常截圖.png
上面這張圖想必大家都不陌生吧马昙!(臥槽桃犬,程序又崩潰了)。
其實控制臺輸出的日志信息就是NSException產(chǎn)生的行楞,一旦程序拋出異常攒暇,程序就會崩潰,控制臺就會有這些崩潰日志子房。
NSException的基本用法
下面代碼就會讓你的程序崩潰
//異常的名稱
NSString *exceptionName = @"自定義異常";
//異常的原因
NSString *exceptionReason = @"我長得太帥了形用,所以程序崩潰了";
//異常的信息
NSDictionary *exceptionUserInfo = nil;
NSException *exception = [NSException exceptionWithName:exceptionName reason:exceptionReason userInfo:exceptionUserInfo];
NSString *aboutMe = @"太帥了";
if ([aboutMe isEqualToString:@"太帥了"])
{
//拋異常 @throw exception;
}
崩潰截圖如下:
自定義崩潰截圖.png
為什么說NSException很強(qiáng)大
NSException掌控著程序的生命,程序的崩潰就是NSException來控制的池颈,你說NSException不強(qiáng)大嗎尾序?那為何要NSException來使程序崩潰呢?其實主要的出發(fā)點是讓開發(fā)者認(rèn)識到哪里的代碼有問題躯砰。
-
下面說兩個NSException的實用技巧吧
1每币、 若自己封裝一套SDK,若要提示哪里出錯琢歇,那么就可以使用NSException兰怠。就像上面NSException的基本用法中的代碼一樣梦鉴。
2、可以用來捕獲異常揭保,防止程序的崩潰肥橙。當(dāng)你意識到某段代碼可能存在崩潰的危險,那么你就可以通過捕獲異常來防止程序的崩潰秸侣。代碼如下
NSString *nilStr = nil;
NSMutableArray *arrayM = [NSMutableArray array];
@try {
//如果@try中的代碼會導(dǎo)致程序崩潰存筏,就會來到@catch
//將一個nil插入到可變數(shù)組中,這行代碼肯定有問題
[arrayM addObject:nilStr];
} @catch (NSException *exception) {
//如果@try中的代碼有問題(導(dǎo)致崩潰),就會來到@catch
//在這里你可以進(jìn)行相應(yīng)的處理操作
//如果你要拋出異常(讓程序崩潰),就寫上
@throw exception
} @finally {
//@finally中的代碼是一定會執(zhí)行的
//你可以在這里進(jìn)行一些相應(yīng)的操作
}
3味榛、最最實用的一個技術(shù)點就是利用 分類(category) + runtime + 異常的捕獲 來防止Foundation一些常用方法使用不當(dāng)而導(dǎo)致的崩潰椭坚。其原理就是利用category、runtime來交換兩個方法搏色,并且在方法中捕獲異常進(jìn)行相應(yīng)的處理善茎。(這里需要了解一些關(guān)于runtime的知識點,若對runtime不熟悉的朋友频轿,可以先去了解下runtime的方法交換)垂涯。下面直接附上大概的使用方法。
- 添加分類航邢,利用runtime交換方法
//
// NSMutableArray+Extension.m
// categoryTest
//
// Created by mac on 16/10/6.
// Copyright ? 2016年 taoyali. All rights reserved.
//#import "NSMutableArray+Extension.h"
#import <objc/runtime.h>
@implementation NSMutableArray (Extension)
+ (void)load {
Class arrayMClass = NSClassFromString(@"__NSArrayM");
//獲取系統(tǒng)的添加元素的方法
Method addObject = class_getInstanceMethod(arrayMClass, @selector(addObject:));
//獲取我們自定義添加元素的方法
Method avoidCrashAddObject = class_getInstanceMethod(arrayMClass, @selector(avoidCrashAddObject:));
//將兩個方法進(jìn)行交換
//當(dāng)你調(diào)用addObject,其實就是調(diào)用avoidCrashAddObject
//當(dāng)你調(diào)用avoidCrashAddObject耕赘,其實就是調(diào)用addObject method_exchangeImplementations(addObject, avoidCrashAddObject);
}
- (void)avoidCrashAddObject:(id)anObject {
@try {
//其實就是調(diào)用addObject
[self avoidCrashAddObject:anObject];
} @catch (NSException *exception) {
//能來到這里,說明可變數(shù)組添加元素的代碼有問題
//你可以在這里進(jìn)行相應(yīng)的操作處理
NSLog(@"異常名稱:%@ 異常原因:%@",exception.name, exception.reason); } @finally {
//在這里的代碼一定會執(zhí)行,你也可以進(jìn)行相應(yīng)的操作
}
}
@end
- 驗證上面的代碼的確可以捕獲異常,并且不會崩潰
NSString *nilStr = nil; NSMutableArray *arrayM = [NSMutableArray array]; [arrayM addObject:nilStr];