2014-09-16 10 views
14

Da Swift derzeit keinen try-catch hat, wie soll ich Abstürze bei fehlerhaften Daten in dieser Codezeile verhindern?NSKeyedUnarchiver Fehlerbehandlung - Absturz in Swift verhindern

var myObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) as MyClass 

UPDATE

habe ich einen sehr einfachen Fall auf einem Spielplatz für die Demonstration. Angenommen, wir wissen nicht, was in data ist, wie kann ich die SIGABRT in der zweiten Zeile fangen? Gibt es keine Möglichkeit zu überprüfen, ob es möglich ist, ein NSData-Objekt vor dem Aufruf von unarchiveObjectWithData zu entpacken?

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

Ich habe das gleiche Problem - haben Sie schon eine Lösung gefunden? –

+0

Noch nicht ... Es sollte wirklich eine Fehlerreferenz als Parameter in die 'unarchiveObjectWithData'-Methode für die Behandlung von objc style und keine Ausnahmen ausgelöst werden .. nicht sicher, wie sie diese mit den Core-Bibliotheken verpasst haben, aber leider. – ccwasden

Antwort

6

Ich denke, die beste Wahl für jetzt, bis Apple die Implementierung von NSKeyedUnarchiver aktualisiert keine Ausnahmen verwenden oder ergänzt Swift Ausnahme Unterstützung, werden Sie einen Objective-C-Wrapper zu verwenden, um zu versuchen, Beifang.

Sie können ein Beispiel für einen Wrapper sehen hier: https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8

Grundsätzlich können Sie eine einzelne Objective-C Funktion oder Klasse vorstellen, dass Sie einen Try-Catch-Block von Swift verwenden können. Ich mag es, das obige Beispiel als Initialisierer zu implementieren, um es in Swift sauberer zu machen:

// 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 
) 
+0

Eine Bibliothek zum Hinzufügen dieser Funktionalität finden Sie in dieser Antwort: http://StackOverflow.com/a/34501525/1518546 –

Verwandte Themen