@throw完成了什么?

时间:2013-07-26 03:57:41

标签: objective-c

我理解@try和@catch块的作用,但@throw做了什么?

@try{

/**Insert code here**/

}

@catch(NSException * myException){

/**insert code **/

}

@throw在哪里适合这一切?一个简单的例子真的很有帮助。

我检查了这个链接,但找不到我要找的答案。

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Exceptions/Tasks/RaisingExceptions.html

3 个答案:

答案 0 :(得分:2)

Objective-C中的异常主要用于明显程序员错误的情况,例如尝试访问NSArray范围之外的元素。相比之下,一些编程语言使用异常来指定任何类型的可恢复错误,例如“找不到文件”,但在Objective-C和Cocoa中,NSException抛出的@throw通常意味着没有什么可以恢复的。

在任何一种情况下,类比是无论在投掷者和捕手之间有多少函数调用,异常都被“抛出”给捕手。这与通过返回值或输出参数返回错误状态的函数形成对比。返回错误状态的函数需要确保链中的所有其他函数返回相同的错误状态,以便另一端的原始调用者知道存在错误。抛出的异常会绕过所有中间函数,并将错误直接发送到原来的调用站点。

void function3()
{
    @throw [NSException exceptionWithName:@"Test" reason:@"Test" userInfo:nil];
}

void function2()
{
    function3();
}

void function1()
{
    function2();
}

int main()
{
    @try
    {
        function1();
    }
    @catch(NSException *ex)
    {
        // handle exception that occurred 3 functions deep
    }
}

通常,由于内存管理的工作方式,您应该避免在Objective-C中抛出异常作为捕获可恢复错误的一般方法。在上文中,如果在function1function2function3中分配了任何对象但自动释放,则这些对象的内存将被泄露。启用了“完全异常安全”的ARC能够检测这些情况并对其进行适当处理,但这仅适用于您自己代码中的对象,而不适用于您可能使用的外部库分配的任何内存。一般期望您的应用程序无法从@throw抛出的异常中恢复。

查看更多详情in this Q&A

答案 1 :(得分:1)

@throw让你,等待它,抛出一个异常,以及我们为什么要抛出异常? 当异常事件发生时我们抛出异常,例如,在下面的代码中,库存数组大小为零是没有意义的,所以我们抛出异常,对于那种特殊情况。

NSString *getRandomCarFromInventory(NSArray *inventory) {
    int maximum = (int)[inventory count];
    if (maximum == 0) {
        NSException *e = [NSException
                         exceptionWithName:@"EmptyInventoryException"
                         reason:@"*** The inventory has no cars!"
                         userInfo:nil];
        @throw e;
    }
    int randomIndex = arc4random_uniform(maximum);
    return inventory[randomIndex];
}

此示例提供了有关以下内容的更多信息:http://rypress.com/tutorials/objective-c/exceptions.html (强调我的)

  

iOS或OS X时可能会出现两种不同类型的问题   应用程序正在运行例外代表程序员级别的错误   比如试图访问不存在的数组元素。 他们是   旨在通知开发人员意外情况   发生了。由于它们通常会导致程序崩溃,   生产代码中很少会出现异常。

答案 2 :(得分:1)

如果操作失败并引发异常,例如:

@try{ // code fails and raises an exception 
      if (!objectNotInMemory)
      {
          @throw exc; // presuming you already initialized NSException* exc
      }
}
@catch (NSException* e){ // deal with exception exc
    if ([[e reason] isEqualToString:@"Object not in memory"])
    UIAlertView* alert = [UIAlertView initWith...];
}

引发该异常的事情(在这种情况下,objectNotInMemory不存在,nil或0)有一个@throw{}指令,用于创建或传递某种NSException对象或消息。然后可以在@catch{}块中捕获此异常对象,或者如果忽略,则会提醒操作系统关闭应用程序进程。

必须抛出异常才能被抓住。

更多阅读Apple的文档(你应该感到满意):

  

@try - 定义一个代码块,它是一个异常处理域:   可能引发异常的代码。

     

@catch() - 定义包含用于处理异常的代码的块   抛出@try块。 @catch的参数是例外   在本地抛出的对象;这通常是一个NSException对象,但可以   是其他类型的对象,例如NSString对象。

     

@finally - 定义随后的相关代码块   执行是否抛出异常。

     

@throw - 抛出异常;这个指令几乎完全相同   对NSException的raise方法的行为。你经常扔   NSException对象,但不限于此。欲获得更多信息   关于@throw,请参阅“抛出异常。”