首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Swift捕捉NSException

用Swift捕捉NSException
EN

Stack Overflow用户
提问于 2015-09-24 10:16:32
回答 6查看 32.4K关注 0票数 88

Swift中的下列代码引发NSInvalidArgumentException异常:

代码语言:javascript
复制
task = NSTask()
task.launchPath = "/SomeWrongPath"
task.launch()

我怎样才能抓住这个例外呢?据我所知,在Swift中尝试/捕获是针对在Swift中抛出的错误,而不是针对从NSExceptions (我猜是用ObjC编写的)对象引发的错误。我是斯威夫特的新手,也许我错过了一些显而易见的东西.

编辑:这是一个针对bug的雷达(特别是针对NSTask):Openradar.apppot.com/22837476

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-04-06 14:54:26

下面是一些代码,它将NSExceptions转换为Swift 2错误。

现在你可以用

代码语言:javascript
复制
do {
    try ObjC.catchException {

       /* calls that might throw an NSException */
    }
}
catch {
    print("An error ocurred: \(error)")
}

ObjC.h:

代码语言:javascript
复制
#import <Foundation/Foundation.h>

@interface ObjC : NSObject

+ (BOOL)catchException:(void(^)(void))tryBlock error:(__autoreleasing NSError **)error;

@end

ObjC.m

代码语言:javascript
复制
#import "ObjC.h"

@implementation ObjC 

+ (BOOL)catchException:(void(^)(void))tryBlock error:(__autoreleasing NSError **)error {
    @try {
        tryBlock();
        return YES;
    }
    @catch (NSException *exception) {
        *error = [[NSError alloc] initWithDomain:exception.name code:0 userInfo:exception.userInfo];
        return NO;
    }
}

@end

别忘了把这个添加到你的“*-桥接头”中:

代码语言:javascript
复制
#import "ObjC.h"
票数 153
EN

Stack Overflow用户

发布于 2015-10-07 11:56:49

我建议的是创建一个C函数,它将捕获异常并返回一个NSError。然后,使用这个函数。

该函数可以如下所示:

代码语言:javascript
复制
NSError *tryCatch(void(^tryBlock)(), NSError *(^convertNSException)(NSException *))
{
    NSError *error = nil;
    @try {
        tryBlock();
    }
    @catch (NSException *exception) {
        error = convertNSException(exception);
    }
    @finally {
        return error;
    }
}

在一些桥接的帮助下,你只需打电话:

代码语言:javascript
复制
if let error = tryCatch(task.launch, myConvertFunction) {
    print("An exception happened!", error.localizedDescription)
    // Do stuff
}
// Continue task

注:我没有真正测试它,我找不到一个快速和简单的方式有目标-C和Swift在一个游乐场。

票数 13
EN

Stack Overflow用户

发布于 2015-12-28 22:10:29

TL;DR:使用迦太基包含https://github.com/eggheadgames/SwiftTryCatch或CocoaPods以包含 https://github.com/ravero/SwiftTryCatch

然后,您可以使用这样的代码,而不必担心它会使您的应用程序崩溃:

代码语言:javascript
复制
import Foundation
import SwiftTryCatch

class SafeArchiver {

    class func unarchiveObjectWithFile(filename: String) -> AnyObject? {

        var data : AnyObject? = nil

        if NSFileManager.defaultManager().fileExistsAtPath(filename) {
            SwiftTryCatch.tryBlock({
                data = NSKeyedUnarchiver.unarchiveObjectWithFile(filename)
                }, catchBlock: { (error) in
                    Logger.logException("SafeArchiver.unarchiveObjectWithFile")
                }, finallyBlock: {
            })
        }
        return data
    }

    class func archiveRootObject(data: AnyObject, toFile : String) -> Bool {
        var result: Bool = false

        SwiftTryCatch.tryBlock({
            result =  NSKeyedArchiver.archiveRootObject(data, toFile: toFile)
            }, catchBlock: { (error) in
                Logger.logException("SafeArchiver.archiveRootObject")
            }, finallyBlock: {
        })
        return result
    }
}

@BPCorp接受的答案如我们所愿,但正如我们所发现的,如果您尝试将这个目标C代码合并到大多数Swift框架中,然后运行测试,事情就会变得有点有趣。我们在找不到类函数时遇到了问题(错误:使用未解析的标识符)。因此,由于这个原因,以及一般的易用性,我们把它打包成一个迦太基库,供一般使用。

奇怪的是,我们可以在其他地方使用Swift + ObjC框架,没有任何问题,只是框架的单元测试在苦苦挣扎。

社会复兴党要求!(这将是一个组合CocoaPod和迦太基的建设,并有一些测试)。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32758811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档