2014-07-01 16 views
7

ich diesen Swift Tutorial bin gerade und es gibt diese Zeile:UIButton als UIButton in swift?

var button:UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton 

zwei Fragen:

  1. warum diese Linie mit as UIButton zu Ende geht? Ist die Zeile nicht klar genug, dass der Benutzer eine Schaltfläche vom Systemtyp erstellen möchte? Es scheint überflüssig zu sein.
  2. ist es notwendig, den Typ UIButton im ersten Teil der Zeile zu deklarieren? Oder mit anderen Worten, nicht genug, um es zu erklären, wie

var button = UIButton.buttonWithType (UIButtonType.System)

Ich meine, wenn der Teil nach dem Gleichheitszeichen wird initialisiert eine Schaltfläche vom Systemtyp ist nicht genug, dass der Compiler daraus schließen kann button ist ein UIButton? Ich meine, Apple sagte, der Compiler sei schlau, um Typen abzuleiten.

+0

Viele ** Ihre ** Fragen sind * neugierig * grundlegende Fragen, die ich wollte auch (fragen, aber ich denke, Du bist 2 Jahre in der Lernkurve vor mir. Normalerweise wirst du keine Antworten auf solche Fragen finden, wenn du nicht nach SO gefragt wirst. – Honey

Antwort

10

Sie müssen die as UIButton gedrückt halten. buttonWithType() zurückgeben AnyObject!, nicht UIButton, so dass die Downcast notwendig ist. Ansonsten müssen Sie die Variable nicht explizit mit : UIButton eingeben. Da der Rückgabetyp buttonWithType() in UIButton als Downcast angegeben ist, wird der Variablentyp als UIButton gewertet. Dies ist, was Sie verwenden sollten:

var button = UIButton.buttonWithType(UIButtonType.System) as UIButton 
+11

Und der zugrunde liegende Grund scheint zu sein, dass die Objective-C-Methode 'buttonWithType:' als Rückgabe von 'id' anstelle von 'instancetype' deklariert wird. –

+2

perfekte Anser und perfekte Kommentar von Martin! Jetzt sehe ich, AnyObject! = id! Vielen Dank!!! – SpaceDog

+0

Ab Swift 1.2 müssen Sie 'as!' Verwenden, um einen Downcast –

2

Wenn Sie das buttonWithType klicken cmd Sie seine dass in swift sehen wie

erklärt
class func buttonWithType(buttonType: UIButtonType) -> AnyObject! 

Da der Typ es zurückgibt, ist ANYOBJECT! Sie müssen es in UIButton zurückgeben.

+3

seine tatsächlich eine optionale und es kann Null sein – Sulthan

+0

Sie sind richtig, ich dachte voraus, wird meinen Beitrag bearbeiten, danke für den Fang. –

7

Einige zusätzliche Hintergrundinformationen zusätzlich zu den bereits gegebenen Antworten: Die Objective-C-Methode

+ (id)buttonWithType:(UIButtonType)buttonType 

kehrt id. Dies war der "traditionelle" Weg, eine "Factory-Methode" so zu deklarieren, dass sie auch von Unterklassen verwendet werden kann. Es gibt keine Art notwendig gegossen in

UIButton *button = [UIButton buttonWithType: UIButtonTypeSystem]; 

weil id kann auf jeden Objective-C-Zeiger umgewandelt werden.

Nun entspricht Typ id in Swift ist AnyObject, und das obige Verfahren wird gemappt

class func buttonWithType(buttonType: UIButtonType) -> AnyObject! 

Swift ist viel strenger und tut nicht implizit Typen umwandeln, damit der Rückgabewert muss sein gieße UIButton ausdrücklich:

var button = UIButton.buttonWithType(UIButtonType.System) as UIButton 

die "moderne" appro ach, um Factory-Methoden zu deklarieren, ist instancetype (siehe zum Beispiel http://nshipster.com/instancetype/ oder Would it be beneficial to begin using instancetype instead of id?).Ein einfaches Beispiel ist die NSString Methode

+ (instancetype)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc 

die in Swift

class func stringWithCString(cString: CString, encoding enc: UInt) -> Self! 

Self ist die Art des Objekts, auf dem das Verfahren aufgerufen wird abgebildet wird, so dass der Rückgabetyp der

NSString.stringWithCString("foo", encoding: NSUTF8StringEncoding) 

ist NSString! und der Rückgabetyp von

NSMutableString.stringWithCString("bar", encoding: NSUTF8StringEncoding) 

ist NSMutableString!. Kein Typ ist notwendig in Swift. Im folgenden Beispiel "weiß" der Swift-Compiler, dass str ist ein NSString:

var str = NSString.stringWithCString("foo", encoding: NSUTF8StringEncoding) 
var cs = str.UTF8String 

Die Rahmen Foundation headers already instancetype in vielen Orten verwenden, aber nicht noch überall, wo möglich (wie in buttonWithType:). Dies kann in zukünftigen Versionen der SDKs in verbessert werden.

+0

Wie ist das Tasten * Klasse * Methoden? Oder ist das eine ** Instanz ** einer UIButton gleich einer der Factory-Methoden/Klassenmethoden der UIButton? – Honey

+0

@Honey: 'UIButton.buttonWithType (...)' ist eine Klassenmethode (oder besser: war als Klassenmethode in Swift 1). –

+0

Ich bekomme diesen Teil, aber nicht nur verwirrt wie in, wie etwas, das mutiert und ist eine Instanz ist von einer Klassenmethode abgeleitet – Honey

0

Swift 2.1 ist jetzt

var button = UIButton(type: .System) 

so keine Notwendigkeit, mit .buttonWithType zu niedergeschlagenen