Обработка ошибок NSKeyedUnarchiver - предотвращение сбоев в Swift

Так как Swift в настоящее время не имеет try-catch, как я должен предотвращать сбои с плохими данными в этой строке кода?

var myObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) as MyClass

UPDATE

Я создал очень простой случай на игровой площадке для демонстрации. Предположим, что мы не знаем, что в data, как я могу поймать SIGABRT во второй строке? Нет ли способа проверить, чтобы можно было разблокировать объект NSData до вызова unarchiveObjectWithData?

var data = "foo bar".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
if let unarc = NSKeyedUnarchiver.unarchiveObjectWithData(data) { // Execution was interrupted: signal SIGABRT
}

Ответы

Ответ 1

Я думаю, что на данный момент лучше всего, пока Apple не обновит реализацию NSKeyedUnarchiver, чтобы не использовать исключения или добавлять поддержку исключений для Swift, вам придется использовать обертку Objective-C для try-catch.

Здесь вы можете увидеть пример оболочки: https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8

По существу, вы можете ввести одну функцию или класс Objective-C, который позволит вам использовать блок try-catch из Swift. Мне нравится реализовать приведенный выше пример в качестве инициализатора, чтобы сделать его более чистым в Swift:

// In Objective-C
// ----------------------

@interface try: NSObject

- (id)initWithTry:(void(^)())try catch:(void(^)(NSException *exception))catch finally:(void(^)())finally;

@end

@implementation try

- (id)initWithTry:(void(^)())try catch:(void(^)(NSException *exception))catch finally:(void(^)())finally
{
    self = [super init];
    if (self) {
        @try {
            try ? try() : nil;
        }
        @catch (NSException *exception) {
            catch ? catch(exception) : nil;
        }
        @finally {
            finally ? finally() : nil;
        }
    }
    return self;
}

@end

// From Swift (make sure you import the objc header in your bridging header
// ----------------------

var data = "foo bar".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
try(
    try: { () -> Void in
        if let unarc: AnyObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) { // Execution was interrupted: signal SIGABRT
            println(unarc)
        }
    },
    catch: { exception in
        println("Failed to parse data: \(exception)")
    },
    finally: nil
)