Swift 2.0exception处理
我们想知道整个SWIFT代码块的error handling机制。
因为,在迅速,有一些技术用于error handling,其中一些就像使用guard
或if let
。 我们也可以使用do - catch
语句来实现它。 但是我们在使用单个try-catch块来处理大量代码时遇到了困难,就像我们在Objective-C
中所做的那样。 在Objective-C
这个块很容易处理任何代码行中的错误。 所以我们想迅速地知道这种机制。
现在,我们知道如果我们需要处理错误,那么对每行使用guard
, if-let
语句,或者编写一些自定义的方法来抛出错误,并在do-catch
块中使用该方法。 那么Swift中有没有什么机制可以像Objective-C
一样与try-catch
块并行,所以我们不需要为整行代码中的每一行代码编写if-let
或guard
语句。
这就是我们如何使用if-let
和guard
让单行声明为null处理:
if-let
实现示例代码片段: –
if let title = dict["title"].string { let myTitle = title }
但是下面提到了我们希望在代理函数中用于try-catch
块的swift解决scheme。
Objective-C
使用try-catch
块的示例代码片段
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { @try { static NSString *itemIdentifier = @"CustomCell"; //Some line of code where exception may occur… //Some line of code where exception may occur… //Some line of code where exception may occur… //Some line of code where exception may occur… //… //… //… return cell; } @catch (NSException *exception) { NSLog(@"Exception in cellForItemAtIndexPath - %@“,exception.description); } }
以上是我们在Objective-C
中使用的代码片段。 但是现在我们想在Swift中使用try-catch
东西。 但直到现在我们还没有find任何解决办法。 那么我们如何处理这样一个场景,在这个场景中我们可以添加try-catch
块来委托table view,collection view,…等等的function。
正如@JeremyP所说的那样,没有例外。 为了清楚起见,你可以使用一个单独的do-catch
块来捕获多个错误,但是if-let
和guard
来避免致命错误是不可捕捉的。 例如:
do { try method1() try method2() } catch { // do something with the error }
但前面的示例不会处理致命错误,例如:
do { try method1() let myVar = anOptionalVar! } catch { }
这段代码将不会处理一个致命的错误,如果anOptionalVar是nil
,你强制解包它,这将导致致命的错误,将终止执行。
所以@JeremyP描述的模式应该被用来处理错误:
enum myError: ErrorType { case BadError } do { guard let myVar = anOptionalVar else { throw MyError.BadError } } catch MyError.BadError { // do something with the error }
因此,从swift 2开始,没有办法使用guard
和if-let
来保证安全,避免致命错误,唯一的select是使用它们并传播一个ErrorType
。
在Swift中,没有例外。 在Objective-C中,也有例外,但是除了程序终止问题之外,你不应该使用它们。 原因是如果一个方法调用其他抛出exception的方法,而且它不处理这个exception本身,它肯定会泄漏资源(内存,文件描述符等)。
在Swift中,你可以抛出一个错误,但这在概念上是NSError**
模式的语法糖。 你可以抛出符合ErrorType
协议的任何东西,但是我认为你只能在枚举上添加它。 话虽如此, NSError
符合ErrorType
所以你可以抛出一个NSError
。
你可以声明一个抛出这样的错误的函数
enum MyError: ErrorType // Protocol for all errors that can be thrown { case ReallyBad case NotSoBad } func aFuncThatThrows(foo: Int) throws -> Int { guard foo >= 0 else { throw MyError.NotSoBad } // Other stuff }
当你使用这样的函数时,你必须试着标记它,以便调用者知道可以抛出错误。
let bar = try aFuncThatThrows(-1)
你所在的函数必须通过throws
关键字声明来重新抛出错误,或者必须处理do { ... } catch
结构的错误。
do { let bar = try aFuncThatThrows(-1) } catch { // handle errors }
如果需要,可以有多个catch块来处理不同types的错误。 例如
catch MyError.ReallBad { // Handle really bad errors } catch MyError.NotSoBad { // handle not so bad errors } catch { // Handle anything else - catches must be exhaustive. }