zoukankan      html  css  js  c++  java
  • (转)iOS被开发者遗忘在角落的NSException-其实它很强大

    转载自 http://www.jianshu.com/p/05aad21e319e

    iOS被开发者遗忘在角落的NSException-其实它很强大

    字数597 阅读968 评论4 

    NSException是什么?

    最熟悉的陌生人,这是我对NSException的概述,为什么这么说呢?其实很多开发者接触到NSException的频率非常频繁,但很多人都不知道什么是NSException,不知道如何使用NSException。下面从一张截图开始讲起NSException。


    崩溃截图.png

    上面这张图想必大家都不陌生吧!(卧槽,程序又崩溃了)。

    其实控制台输出的日志信息就是NSException产生的,一旦程序抛出异常,程序就会崩溃,控制台就会有这些崩溃日志。


    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很强大

    NSException掌控着程序的生命,程序的崩溃就是NSException来控制的,你说NSException不强大吗?那为何要NSException来使程序崩溃呢?其实主要的出发点是让开发者认识到哪里的代码有问题。

    下面说两个NSException的实用技巧吧

    • 1、 若自己封装一套SDK,若要提示哪里出错,那么就可以使用NSException。就像上面NSException的基本用法中的代码一样。
    • 2、可以用来捕获异常,防止程序的崩溃。当你意识到某段代码可能存在崩溃的危险,那么你就可以通过捕获异常来防止程序的崩溃。代码如下
        NSString *nilStr = nil;
        NSMutableArray *arrayM = [NSMutableArray array];
    
        @try {
            //如果@try中的代码会导致程序崩溃,就会来到@catch
    
            //将一个nil插入到可变数组中,这行代码肯定有问题
            [arrayM addObject:nilStr];
        }
        @catch (NSException *exception) {
            //如果@try中的代码有问题(导致崩溃),就会来到@catch
    
            //在这里你可以进行相应的处理操作
    
            //如果你要抛出异常(让程序崩溃),就写上 @throw exception
    
        }
        @finally {
    
            //@finally中的代码是一定会执行的
    
            //你可以在这里进行一些相应的操作
        }
    • 3、最最实用的一个技术点就是利用 分类(category) + runtime + 异常的捕获 来防止Foundation一些常用方法使用不当而导致的崩溃。其原理就是利用category、runtime来交换两个方法,并且在方法中捕获异常进行相应的处理。(这里需要了解一些关于runtime的知识点,若对runtime不熟悉的朋友,可以先去了解下runtime的方法交换)。下面直接附上大概的使用方法。

    添加分类,利用runtime交换方法

    //
    //  NSMutableArray+Extension.m
    //  categoryTest
    //
    //  Created by mac on 16/10/6.
    //  Copyright © 2016年 chenfanfang. All rights reserved.
    //
    
    #import "NSMutableArray+Extension.h"
    
    #import <objc/runtime.h>
    
    @implementation NSMutableArray (Extension)
    
    + (void)load {
    
        Class arrayMClass = NSClassFromString(@"__NSArrayM");
    
        //获取系统的添加元素的方法
        Method addObject = class_getInstanceMethod(arrayMClass, @selector(addObject:));
    
        //获取我们自定义添加元素的方法
        Method avoidCrashAddObject = class_getInstanceMethod(arrayMClass, @selector(avoidCrashAddObject:));
    
        //将两个方法进行交换
        //当你调用addObject,其实就是调用avoidCrashAddObject
        //当你调用avoidCrashAddObject,其实就是调用addObject
        method_exchangeImplementations(addObject, avoidCrashAddObject);
    }
    
    - (void)avoidCrashAddObject:(id)anObject {
    
        @try {
            [self avoidCrashAddObject:anObject];//其实就是调用addObject
        }
        @catch (NSException *exception) {
    
            //能来到这里,说明可变数组添加元素的代码有问题
            //你可以在这里进行相应的操作处理
    
            NSLog(@"异常名称:%@   异常原因:%@",exception.name, exception.reason);
        }
        @finally {
            //在这里的代码一定会执行,你也可以进行相应的操作
        }
    }
    
    @end

    验证上面的代码的确可以捕获异常,并且不会崩溃

        NSString *nilStr = nil;
        NSMutableArray *arrayM = [NSMutableArray array];
        [arrayM addObject:nilStr];

    控制台输出截图如下


    捕获到的异常信息.png

    利用category + runtime + 异常的捕获 来写一个防止崩溃的框架

  • 相关阅读:
    蜗牛讲-Fabric入门之架构
    No module named flask 错误解决
    adb测试Doze和App Standby模式
    以太坊挖矿原理
    mac上 go-delve 安装出现The specified item could not be found in the keychain 解决方法
    nginx+lua 根据指定路径反向代理
    asp.net 网站监控方案
    go开源项目influxdb-relay源码分析(一)
    碰到的jpython用ssh连接机器,有些命令无法运行
    git常用命令(备忘)
  • 原文地址:https://www.cnblogs.com/funny11/p/6084706.html
Copyright © 2011-2022 走看看