2015-02-13 14 views
10

I aktualisiert nur von schnellen 1,1 bis swift 1.2 und Compiler-Fehler:Swift 1.2 redeclares Objective-C-Methode

Method 'setVacation' redeclares Objective-C method 'setVacation:' 

Hier einige Code:

var vacation : Vacation? 
func setVacation(_vacation : Vacation) 
{...} 

Aber ich anrufen müssen setVacation

Gibt es Vorschläge, wie das zu beheben ist?

Antwort

8

Dies ist Ursache durch die Änderung in Xcode angegeben 6.3beta Release Notes:

Swift now detects discrepancies between overloading and overriding in the Swift type system and the effective behavior seen via the Objective-C runtime. (18391046, 18383574) For example, the following conflict between the Objective-C setter for “property” in a class and the method “setProperty” in its extension is now diagnosed:

class A : NSObject { 
    var property: String = "Hello" // note: Objective-C method 'setProperty:’ 
            // previously declared by setter for 
            // 'property’ here 
} 
extension A { 
    func setProperty(str: String) { } // error: method ‘setProperty’ 
             // redeclares Objective-C method 
             //'setProperty:’ 
} 

dies zu beheben Sie alles, was Sie brauchen, um Methodensignaturen eindeutig (wie Objective-C bietet keine -Methodenüberladung)

Oder erben Sie nicht von NSObject, wenn Sie Swift nur Klasse benötigen.

+0

Dies wird angezeigt Dies impliziert, dass das Überladen von Methoden in solchen Klassen wie UIViewControllern oder in der Tat keiner Klasse, die eine Klasse von objective-c unterklassifiziert, möglich ist. Ist das korrekt? –

+0

Es scheint die saubere Problemumgehung zu sein, diese privaten zu deklarieren. Auf diese Weise versucht der Compiler nicht, sie in ObjC zu konvertieren, so dass kein Konflikt entsteht. – kwerle

+0

@ kwerle Awesome Problemumgehung. Daran habe ich vorher nicht gedacht. – Kirsteins

1

Wie von @ Kirsteins bemerkt, erkennt Swift nun widersprüchliche Symbole zwischen Swift und Obj-C und schnelle Symbole, die Obj-C-Kummer verursachen würden. Zusätzlich zu der Antwort, können Sie dies in der Regel vermeiden, indem ein erforderliches Etikett für die zusätzlichen Typen spezifizieren, so dass der Anruf Signatur zu ändern:

import Foundation 

extension NSObject { 
    func foo(d:Double, i:Int) { println("\(d), \(i)") } 
    func foo(withInt d:Int, i:Int) { println("\(d), \(i)") } 
} 

let no = NSObject() 
no.foo(withInt:1, i: 2) 

Darüber hinaus aber, und Ihre unmittelbare Frage zu beantworten, Sie versuchen, Obj-C-Idiome auf Swift anwenden. Was Sie wirklich wollen, ist entweder zu implementieren didSet (höchstwahrscheinlich) oder möglicherweise set:

class WhatIDidLastSummer { 

    var vacation:Bool = false { 
     didSet { 
      // do something 
     } 
    } 

    var staycation:Bool { 
     get { return true } 
     set { 
      // do something 
     } 
    } 

} 
+0

Ich habe ein ähnliches Problem, aber es ist nicht in einer SetX-Methode. Ich mache den Auftrag vom iTunesU Stanford Swift Kurs. Als ich zu Swift 1.2 konvertiert habe, stoppte etwas Code, der kompiliert wurde, kompiliert. Die Methode ist performOperation. –

+0

2 Methoden mit unterschiedlichen Signaturen. "func performOperation (Operation: (Double, Double) -> Double)", und: "func performOperation (Operation: (Double) -> Double)". Die erste erhält keinen Fehler, die zweite jedoch. (Der Fehler ist: "Methode 'performOperation' deklariert Objective-C-Methode 'performOperation:'"). Ich könnte "performOperation" als eine echte ObjC-Methode irgendwo sehen ... aber warum erzeugt dann nicht die erste Methode den Fehler? –

+0

(ohne Ihren Kontext zu kennen), weil dieser bestimmte Code entweder von NSObject abgeleitet ist oder als @objc markiert ist und Obj-C das Überladen von Funktionen/Methoden nicht unterstützt, auch nicht mit anderen Typ-Signaturen. TL, DR, wird es in einer Nur-Swift-Umgebung gut funktionieren, aber Obj-C kann es nicht verwenden, und der Code wird entweder von Obj-C abgeleitet oder Obj-C zur Verfügung gestellt. –

4

Cappy: Für die Standford Problem, das ich einfach diese verwendet, weil es wie der Xcode Beta sieht einfach sagt, dass der Betrieb: (Double, Double) -> Double ist das gleiche wie Operation: Double -> Double, ich weiß nicht, ob es ein Bug ist oder nicht ...

Aber der Code unten funktioniert, aber ist NICHT sauber :(

func performOperation(r:String? = "2", operation: (Double, Double) -> Double) { 
    if operandStack.count >= 2 { 
     displayValue = operation(operandStack.removeLast(), operandStack.removeLast()) 
     enter() 
    } 
} 

func performOperation(operation: Double -> Double) { 
    if operandStack.count >= 1 { 
     displayValue = operation(operandStack.removeLast()) 
     enter() 
    } 
}