2016-05-10 10 views
0

Mein Projekt verwendet sowohl Swift als auch Objective C. Ich habe ein Singleton in Objective C geschrieben, das als eine Eigenschaft des Typs NSDictionary.Überprüfen, ob [NSObject: AnyObject]! ist NSNull in Swift

Dies ist eine alte Klasse, die während meines gesamten Projekts verwendet wird. Ich versuche, diese Klasse in einer Swift-Klasse zu verwenden, wie dies

if let dict = DataManager.sharedManager().currentDictionary 
{ 
    // 
} 

Das Problem, das ich bin vor ist, dass currentDictionary gesetzt wird vom Server unter Verwendung von Daten. Manchmal könnte dies

In Objective-C-Klassen sein, ich die Situation mit der folgenden Kontroll

if ([currentDictionary isKindOfClass: [NSNull class]]) 
{ 
    // Do nothing 
} 

Aber ich bin nicht sicher umgehen kann, wie man eine ähnliche Prüfung in Swift zu implementieren. Ich habe versucht, die folgenden

if let data = DataManager.sharedManager().currentDictionary as? NSNull 
{ 
    return 
} 

Aber es nicht und ich erhalte Warnung einen Compiler auch funktioniert:

„Cast von‚[NSObject: ANYOBJECT]‘an unabhängigem Typ‚NSNull‘immer versagt“

Dies unterscheidet sich von der Überprüfung auf Null-Werte innerhalb der Dicitonary, wie sie AnyObject sein werden und ich kann versuchen, sie in den Typ zu werfen, die ich überprüfen möchte.

Kann jemand bitte alle Hinweise geben, wie diese Situation richtig

+2

Das 'NSDictionary' sollte *** *** niemals vom Typ' NSNull' sein. Der Inhalt kann sein, aber nicht das Wörterbuch selbst. – luk2302

+1

Dieser Beitrag ist wahrscheinlich nützlich für Sie http://stackoverflow.com/questions/24026609/detect-a-null-value-in-nsdictionary – HDT

+0

@ luk2302 .. Ja, sollte es nicht sein. Ich habe dasselbe mit der Serverseite mitgeteilt. Aber ich möchte auch einen Sicherheitscheck beim Kunden hinzufügen. – humblePilgrim

Antwort

1

zu behandeln Wenn Sie überprüfen möchten, ob currentDictionarynil oder nicht, können Sie verwenden:

guard let currentDictionary = DataManager.sharedManager().currentDictionary else { 
    return 
} 

ersetzen guard-else Anweisung mit if-else wenn Du willst nicht früh zurückkehren.

Wenn Sie Inhalte von currentDictionary validieren möchten ist NSNull oder nicht:

if let value = DataManager.sharedManager().currentDictionary["key"] { 
    // do something with value 
} 
+0

Ich habe die Guard-Anweisung versucht, aber es hilft auch nicht. Ich denke, es prüft auf Null, was fehlschlägt, da es tatsächlich ein NSNull-Objekt gibt. – humblePilgrim

+0

Was ist, wenn Sie 'guard DataManager.sharedManager() verwenden. CurrentDictionary ist NSNull else {return}'? – mro

+0

Die gleiche Warnung wird generiert – humblePilgrim

2

Zunächst einmal, wenn die Variable etwas anderes, das NSDictionary enthalten kann, richte nicht seine Art zu NSDictionary. Swift ist typsicher und vertraut dem angegebenen Typ.

Die einfachste Problemumgehung wäre, es in Objective-C id zu machen.

dann in Swift können Sie einfach:

guard let data = DataManager.sharedManager().currentDictionary as? NSDictionary else { 
    return 
} 

Wenn Sie nicht den ursprünglichen Code ändern können, erstellen Sie einfach eine Swift-Accessor mit der richtigen Art, die eine Kategorie, z.B.

@interface DataManager (Swift) 

// solution 1, will be converted to AnyObject in Swift 
- (id)currentDictionaryForSwift1; 

// solution 2, let's handle NSNull internally, don't propagate it to Swift 
- (NSDictionary *)currentDictionaryForSwift2; 

@end 

@implementation DataManager 

- (id)currentDictionaryForSwift1 { 
    return self.currentDictionary; 
} 

- (NSDictionary *)currentDictionaryForSwift2 { 
    if (self.currentDictionary == [NSNull null]) { 
     return nil; 
    } 

    return self.currentDictionary; 
}  

@end 

Ich würde Ihnen empfehlen, intern zu behandeln. Es sollte nicht notwendig sein, dass ein anderer Code nil und separat behandelt.

Man könnte es tatsächlich lösen bereits im Getter:

- (NSDictionary *)currentDictionary { 
    if (_currentDictionary == [NSNull null]) { 
     return nil; 
    } 

    return _currentDictionary; 
} 

oder in der Setter

- (void)setCurrentDictionary:(NSDictionary *)currentDictionary { 
    if (currentDictionary == [NSNull null]) { 
     _currentDictionary = nil; 
    } else { 
     _currentDictionary = currentDictionary; 
    } 
} 

Wie Sie sehen können, gibt es mehrere Lösungen, aber die beste Lösung sollte verbessern auch Ihre Obj -C-Code. Der Unterschied zwischen und nil sollte lokal behandelt und nicht propagiert werden.

Verwandte Themen