2016-04-12 20 views
0

Ich versuche, diesen SWIFT-Code in Objective-CSwift Bequemlichkeit init mit Switch-Anweisung zu Objective-C

convenience init(fromString string: String, format:DateFormat) 
    { 
     if string.isEmpty { 
      self.init() 
      return 
     } 

     let string = string as NSString 

     switch format { 

     case .DotNet: 

      let startIndex = string.rangeOfString("(").location + 1 
      let endIndex = string.rangeOfString(")").location 
      let range = NSRange(location: startIndex, length: endIndex-startIndex) 
      let milliseconds = (string.substringWithRange(range) as NSString).longLongValue 
      let interval = NSTimeInterval(milliseconds/1000) 
      self.init(timeIntervalSince1970: interval) 

Bisher zu konvertieren, ich tue dies:

-(id) initFromString: (NSString *) string format: (DateFormat *) format{ 
    if (string == nil) { 
     self = [self init]; 
     return self; 
    } 


    switch (format) { 
     case .DotNet: 
      NSRange *startIndex = [[string rangeOfString:@"("] location]+1; 

    } 
} 

und haben bereits in den folgenden Fehlern führen:

für die switch(format): Anweisung erfordert die Expression von integer-Typ (Dateformat * __strong‘ungültig)

und für die 2 folgenden Zeilen: Erwarteter Ausdruck

Irgendwelche Ideen?

+0

war DateFormat eine Enum im Swift-Code? Sie haben es im Objc-Code in eine Klasse umgewandelt und übergeben 'format' als Zeiger auf eine Instanz von DateFormat. Der Compiler möchte nicht, dass Sie einen Zeiger wie diesen einschalten. –

+0

Etwas off-topic, aber in der aktuellen Welt sollte Ihr init "instancetype" anstelle von id zurückgeben. Nur ein praktischer Hinweis für den Compiler. –

Antwort

2

In Objective-C ist die Zeichenfolge implizit optional. Testen für nil testet lediglich, ob eine Zeichenfolge geliefert wurde. Es prüft nicht, ob eine leere Zeichenfolge geliefert wurde. Sie möchten wahrscheinlich auf string.length == 0 umschalten, denn durch die Magie von nil-messaging wird das funktionieren, um nach einer leeren Zeichenfolge oder gar keiner Zeichenfolge zu suchen.

Objective-C verwendet C switch Anweisung. Sie können also nur integrierte Typen einschalten. Wenn dies ursprünglich Objective-C-Code wäre, wäre DateFormat wahrscheinlich ein NS_ENUM - ein Ganzzahl-Typ anstelle eines Objekttyps. Es sieht so aus, als wäre das Original eine Aufzählung von Ihrer Verwendung der Punktsyntax? Wenn Sie es eine Objective-C Aufzählung machen können dann tun und einfach verwenden:

- (id)initFromString:(NSString *)string format:(DateFormat)format { 
    .... 
    switch(format) 
    { 
     case DateFormatDotNet: { 
      .... 
     } break; 
    } 

(mit den geschweiften Klammer innerhalb der case zu sein, weil Sie Variablen deklarieren dort wollen).

Andernfalls, wenn es ein Objekt Format sein soll, dann sind Sie bei einer schmerzhaften Konstruktion, die wie:

if([format isEqual:[DateFormat dotNetFormat]]) { 
} 
else if([format isEqual:[DateFormat otherFormat]]) { 
} 
... etc ... 

auch Objective-C hat eine syntaktische Unterscheidung zwischen struct s, die genau sind, was sie sind in C - benannte Felder, aber keine integrierten Verhaltens- und Objekttypen, was wiederum darauf zurückzuführen ist, dass es sich um eine strikte Obermenge von C handelt. NSRange ist eine Struktur. Daher funktioniert die eckige Klammer-Messaging-Syntax nicht. Statt:

[[string rangeOfString:@"("] location] 

Verwendung:

[string rangeOfString:@"("].location 

Eckige Klammern um den rangeOfString Ruf, weil es ein Nachrichtenversand an ein Objekt ist, dann ist ein Punkt für den Standort, weil Sie wieder eine C-Struktur als Wert erhalten, und so greift man auf ein Feld in einer C-Struktur zu.

(Punktsyntax funktioniert auch für Eigenschaften auf Objective-C-Objekten, sondern explizit Alias ​​Getter und Setter-Anrufe, und nur etwa die jüngsten von Objective-C drei Jahrzehnten)

+0

Was ist mit dem StartIndex Fehler? sagt mir: Schlechter Empfängertyp "NSRange" (aka "struct_NSRange") –

+0

Ein weiterer Rest von Objective-C lässt den Programmierer den Unterschied zwischen 'struct's (das sind die C-Sortierung, dh named-field storage mit nein) analysieren Logik, die entweder Wert oder Referenztypen sind, also ganz anders als die Swift-Sortierung) und Objekte. Ich werde die Antwort aktualisieren. – Tommy

+0

Eine letzte Frage: Wie konvertiert man das in Objective-C? self.init (timeIntervalSince1970: interval) –

0

diesen Code Unter der Annahme, verwendet ist zu How to convert a Swift enum: String into an Objective-C enum: NSString?

Da Ihr Date Variable ein Objekt mit einem dateFormatType, dass ein NSString ist, werden Sie verwenden, um ein verkettete if-else-Konstrukt aus den verschiedenen Möglichkeiten auszuwählen:

if([format.dateFormatType compare: DotNetDateFormatType] == NSOrderedSame) { 
    [self handleDotNetDateFormat: format] 
} else if ([format.dateFormatType compare: RSSDateFormatType] == NSOrderedSame) { 
    [self handleRSSDateFormat: format] 
... 

Objective-C hat kein Konzept der Punktwert-Syntax für Enum-Werte (daher ist ".DotNet" kein gültiger Ausdruck in Objective-C). Deshalb beschwert sich der Compiler über diese beiden Zeilen.

+0

Was ist mit dem StartIndex Fehler? sagt mir: Schlechter Empfängertyp "NSRange" (aka "struct_NSRange") –

+0

Ein NSRange ist eine Struktur, kein Ziel-C-Objekt. Sie verwenden es in einer Nachrichtenübergabestruktur '[[string rangeOfString: @" ("] location]'. Verwenden Sie einfach '[string rangeOfString: @" ("]. Location' –

+0

Vielen Dank für Ihre Hilfe! Ich wünschte, ich könnte gebe +1, aber mein Rep ist nicht hoch genug:/EDIT: Ich könnte es tatsächlich tun, aber es wird nur angezeigt, wenn ich 15 Rep erreiche. –