• 第21条:理解Objective-C错误模型


    首先要注意的是:

    自动引用计数”(Automatic Reference Counting, ARC,参见第30条)在默认情况下不是“异常安全的”(exception safe)。具体来说,这意味着:如果抛出异常,那么本应在作用域末尾释放的对象现在却不会自动释放了。如果想生成“异常安全”的代码,可以通过设置编译器的标志来实现,不过这将引入一些额外代码,在不抛出异常时,也照样要执行这部分代码。需要打开的编译器标志叫做-fobjc-arc-exceptions

    即使不使用ARC,也很难写出在抛出异常时不会导致内存泄漏的代码。

    只要发生了可使整个应用程序崩溃的严重错误时,才应使用异常。异常抛出之后,无须考虑恢复问题,而且应用程序此时也应该退出。这就是说,不用再编写复杂的“异常安全”代码了。

    在错误不那么严重的情况下,可以指派“委托方法”(delegate method)来处理错误,也可以把错误信息放在NSError对象里,经由“输出参数”返回给调用者。

    或令方法返回nil/0以表明其中有错误发生。

    NSError对象里封装了3条信息:

    1、Error domain(错误范围,其类型为字符串)

    错误范围,也就是产生错误的根源,通常用一个特有的全局变量来定义。例:NSURLErrorDomain来表示错误范围。

    2、Error code(错误码,其类型为整数)

    表明在某一特定的范围内可能会发生一系列相关错误,这些错误通常采用enum来定义。

    例:HTTP状态码

    3、User info(用户信息,其类型为字典)

    有关些错误的额外信息,其中或许包含一段“本地化的描述”(localized description)。或许还含有导致该错误发生的另外一个错误,经由此种信息,可将相关错误串成一条“错误链”(chain of errors)。

    NSError经常由“输出参数”返回给调用者。

    例:-(BOOL)doSomething:(NSError**)error

    传递给方法的参数是个指针,而该指针本身又指向另一个指针,那个指针指向NSError对象。或者也可以把它当成一个直接指向NSError对象的指针。

    实际上,在使用ARC时,编译器会把方法签名中的NSError** 转换成NSError* __autoreleasing*,也就是说,指针所指的对象会在方法执行完毕后自动释放。这个对象必须自己释放,因为“doSomething:”方法不能保证其调用者可以把此方法中创建的NSError释放掉,所以必须加入autoreleass

    NSError *error = nil; // 输出参数

    BOOL ret = [object doSomething: &error];

    if(error) {

      // There was an error

      *error = [NSError errorWithDomain:domain code: code userInfo: userInfo]; // *error为error参数“解引用”(dereference)。也就是说,error所指的那个指针现在要指向一个亲的NSError对象了。

    }

  • 相关阅读:
    Java并发辅助类的使用
    使用List需要注意的点
    构造函数、静态变量、代码块执行顺序
    TreeMap源码分析
    大战红黑树
    关于HashMap多线程下环形链表的总结
    LinkedHashMap源码分析
    「HDU 3292」 No more tricks, Mr Nanguo
    「BZOJ 3122」「SDOI2013」 随机数生成器
    「BZOJ3884」 上帝与集合的正确用法
  • 原文地址:https://www.cnblogs.com/Pikdays/p/5734937.html
Copyright © 2020-2023  润新知