如何在Swift 2.0中正确处理NSFileHandle异常?

mir*_*age 16 nsexception nsfilehandle ios swift swift2

首先,我是iOS和Swift的新手,来自Android/Java编程背景.因此,对于我来说,尝试写入文件时捕获异常的想法是第二天性,如果缺少空间,文件权限问题或文件中可能发生的任何其他事情(根据我的经验,已发生) .我也明白,在Swift中,异常与Android/Java不同,所以这不是我在这里要求的.

我试图使用NSFileHandle附加到一个文件,如下所示:

let fileHandle: NSFileHandle? = NSFileHandle(forUpdatingAtPath: filename)
if fileHandle == nil {
    //print message showing failure
} else {
    let fileString = "print me to file"
    let data = fileString.dataUsingEncoding(NSUTF8StringEncoding)
    fileHandle?.seekToEndOfFile() 
    fileHandle?.writeData(data!)
}
Run Code Online (Sandbox Code Playgroud)

但是,函数seekToEndOfFile()writeData()函数都表明它们会抛出某种异常:

如果文件描述符已关闭或无效,如果接收器表示未连接的管道或套接字端点,文件系统上没有剩余空闲空间,或者发生任何其他写入错误,则此方法引发异常. - Apple文档writeData()

那么在Swift 2.0中处理这个问题的正确方法是什么?我读过的联系 斯威夫特语言错误处理,的try-catch斯威夫特例外,NSFileHandle写数据:异常处理,雨燕2.0的异常处理,以及如何捕捉在斯威夫特的例外,但他们都没有直接回答我的问题.我确实读过一些关于在Swift代码中使用objective-C的东西,但由于我是iOS新手,我不知道这个方法是什么,似乎无法在任何地方找到它.我还尝试了新的Swift 2.0 do-catch块,但他们没有意识到NSFileHandle方法会抛出任何类型的错误,很可能因为函数文档没有throw关键字.

我知道我可以让应用程序崩溃,如果它用完了空间或其他什么,但由于应用程序可能会在以后发布到应用商店,我不希望这样.那么我如何以Swift 2.0的方式做到这一点呢?

编辑: 这个目前只是一个只有Swift代码的项目,所以即使看起来有一种方法可以在Objective-C中做到这一点,我也不知道如何将两者混合在一起.

Cas*_*sey 23

第二个(可恢复的)解决方案是创建一个非常简单的ObjectiveC++函数,它接受一个块并返回一个异常.

创建一个名为ExceptionCatcher.h的文件,并在你的桥接头中添加它(如果你还没有,Xcode会提示为你创建一个)

//
//  ExceptionCatcher.h
//

#import <Foundation/Foundation.h>

NS_INLINE NSException * _Nullable tryBlock(void(^_Nonnull tryBlock)(void)) {
    @try {
        tryBlock();
    }
    @catch (NSException *exception) {
        return exception;
    }
    return nil;
}
Run Code Online (Sandbox Code Playgroud)

使用这个帮助很简单,我已经调整了上面的代码来使用它.

func appendString(string: String, filename: String) -> Bool {
    guard let fileHandle = NSFileHandle(forUpdatingAtPath: filename) else { return false }
    guard let data = string.dataUsingEncoding(NSUTF8StringEncoding) else { return false }

    // will cause seekToEndOfFile to throw an excpetion
    fileHandle.closeFile()

    let exception = tryBlock {
        fileHandle.seekToEndOfFile()
        fileHandle.writeData(data)
    }
    print("exception: \(exception)")

    return exception == nil
}
Run Code Online (Sandbox Code Playgroud)

  • 注意,这并没有捕获所有异常,即使它们看起来非常相似.即它将始终捕获某些NSExceptions,同时始终如一地捕获其他NSExceptions.永远不知道为什么. (2认同)