当前位置: 首页 > 知识库问答 >
问题:

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

郤望
2023-03-14

首先,我是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!)
}

但是,seektoendoffile()writedata()函数都指示它们抛出某种异常:

那么在Swift 2.0中处理这个问题的正确方法是什么呢?我已经阅读了Swift语言中的错误处理、Swift中的try-catch异常、NSFileHandle WriteData:异常处理、Swift 2.0异常处理以及如何在Swift中捕获异常的链接,但它们都没有直接回答我的问题。我确实读过一些关于在Swift代码中使用objective-C的东西,但由于我是iOS新手,我不知道这种方法是什么,而且似乎在任何地方都找不到。我还尝试了新的Swift 2.0do-catch块,但它们无法识别NSFileHandle方法引发的任何类型的错误,很可能是因为函数文档没有throw关键字。

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

编辑:目前这是一个只有Swift代码的项目,所以尽管Objective-C中似乎有一种方法可以做到这一点,但我不知道如何将两者融合在一起。

共有1个答案

魏刚豪
2023-03-14

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

创建一个名为:exceptioncatcher.h的文件,并在桥接头中添加import(如果还没有,则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;
}

使用这个帮助器非常简单,我已经从上面修改了我的代码来使用它。

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
}
 类似资料:
  • 我将我的jms队列更改为JMS1。然而,当我执行代码时,我得到一个异常。 我的期望是,每当我得到异常时,我的bean类都应该被调用,但事实并非如此。 runtimeCamelException:org.apache.camel.FailedToCreateRouteException:在以下位置创建路由route1失败:>>>到[jms1:queue:finalqSource]<<<在route:

  • 问题内容: 假设我有某种游戏。我有一个buyItem函数,如下所示: 如果我对该路由进行垃圾邮件处理,直到扣除用户余额(第二次查询),则用户余额仍为正。 我尝试过的 问题是将在第一〜5项要求。因此,这也不起作用。 我们如何处理这种情况?如果重要的话,我正在使用Sails.JS框架。 问题答案: 通过该方法,Sails 1.0现在具有完整的事务支持。例: 更新资料 正如一些评论者所指出的,启用连接池

  • 本文向大家介绍Java中断异常的正确处理方法,包括了Java中断异常的正确处理方法的使用技巧和注意事项,需要的朋友参考一下 处理InterruptedException 这个故事可能很熟悉:你正在写一个测试程序,你需要暂停某个线程一段时间,所以你调用 Thread.sleep()。然后编译器或 IDE 就会抱怨说 InterruptedException 没有抛出声明或捕获。什么是 Interru

  • 问题内容: 我有一个库,其中为我们的客户提供了两种方法,sync和async。他们可以调用他们认为适合其目的的任何方法。 executeSynchronous()-等待直到得到结果,然后返回结果。 executeAsynchronous()-立即返回一个Future,如果需要,可以在完成其他操作之后进行处理。 他们将传递其中包含用户ID的DataKey对象。然后,我们将根据用户ID确定要调用的计算

  • 问题内容: 我一直在概念上为我的项目决定异常处理结构。 假设您有一个示例: 还有两个子类FileData和StaticData,它们从某些指定的文件中读取数据,StaticData仅返回一些预定义的常量数据。 现在,在读取文件时,可能会在FileData中引发IOException,但是StaticData将永远不会抛出。大多数样式指南建议在调用堆栈上传播Exception,直到有足够的上下文可以

  • 假设我有一个类Person,具有不同数据类型的不同属性,我在我的主方法中有这样的代码: 现在,假设高度的赋值引发了一个异常,例如InvalidCastException,代码将停止执行,并且可能会记录一些东西,以防我有一个记录表。问题是,从日志中,我无法确切地理解哪一行和赋值抛出了异常。 是否有任何方法可以捕获异常,并能够记录(数据库中的某个位置)哪个赋值引发异常,以及在这种情况下针对哪种类型的强