Swift native base class lub NSObject

Przetestowałem niektóre Isa swizzling Z Swift, i okazało się, że działa tylko wtedy, gdy NSObject jest super-klasą (bezpośrednio lub Dalej), lub za pomocą dekoracji '@ objc'. W przeciwnym razie będzie on podążał za statycznym-i vtable-dispatch stylu, jak C++.

Czy normalne jest definiowanie klasy Swift bez klasy bazowej Cocoa/NSObject? Jeśli chodzi o mnie, oznacza to rezygnację z dużej dynamiki Objective-C, takiej jak przechwytywanie metod i introspekcja w czasie wykonywania.

Dynamiczne zachowanie w czasie wykonywania znajduje się w Centrum funkcji, takich jak obserwatorzy właściwości, Podstawowe Dane, programowanie zorientowane na aspekt, Wiadomości wyższego rzędu , struktury analityczne i rejestrujące i tak dalej.

Użycie stylu wywołania metody Objective-C dodaje około 20 operandów kodu maszynowego do wywołania metody, więc w pewnych sytuacjach ( wiele ciasnych wywołań do metod o małych ciałach ) wysyłanie statyczne i vtable w stylu C++ może działać lepiej.

Ale podane ogólna zasada 95-5 ( 95% zysków z wydajności pochodzi z strojenia 5% kodu), czy nie ma sensu zaczynać od potężnych funkcji dynamicznych i utwardzać w razie potrzeby?

Author: Community, 2014-06-05

6 answers

Klasy Swift będące podklasami NSObject:

  • są same klasy Objective-C
  • użyj objc_msgSend() do wywołania (większości) ich metod
  • Udostępnij metadane Runtime Objective - C dla (większości) implementacji metod

Klasy Swift, które nie są podklasami NSObject:

  • są klasami Objective-C, ale implementują tylko kilka metod dla zgodności NSObject
  • nie używaj objc_msgSend() do wywołania ich metod (przez default)
  • nie dostarczają metadanych Runtime Objective-C dla ich implementacji (domyślnie)

Podklasowanie NSObject w języku Swift zapewnia elastyczność runtime Objective-C, ale także wydajność Objective - C. Unikanie NSObject może poprawić wydajność, jeśli nie potrzebujesz elastyczności Objective-C.

Edit:

W Xcode 6 beta 6 pojawia się atrybut dynamic. Dzięki temu możemy polecić Swiftowi, że metoda powinna używać dynamicznej wysyłki i będzie dlatego wspieraj przechwytywanie.

public dynamic func foobar() -> AnyObject {
}
 95
Author: Greg Parker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-29 12:26:39

Odkryłem również, że jeśli oparłem klasę Swift na NSObject, zobaczyłem nieoczekiwane zachowanie w czasie wykonywania, które może ukryć błędy kodowania. Oto przykład.

W tym przykładzie, gdzie nie bazujemy na NSObject, kompilator poprawnie dostrzega błąd w testIncorrect_CompilerShouldSpot, raportowanie"... "MyClass" nie jest zamiennikiem dla "MirrorDisposition ""

class MyClass {
  let mString = "Test"

  func getAsString() -> String {
    return mString
  }

  func testIncorrect_CompilerShouldSpot() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject == myString) {
        // Do something
      }
  }

  func testCorrect_CorrectlyWritten() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject.getAsString() == myString) {
        // Do something
      }
  }
}

W tym przykładzie, gdzie bazujemy na NSObject , kompilator nie zauważy błędu w testIncorrect_CompilerShouldSpot:

class myClass : NSObject {
  let mString = "Test"

  func getAsString() -> String {
    return mString
  }

  func testIncorrect_CompilerShouldSpot() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject == myString) {
        // Do something
      }
  }

  func testCorrect_CorrectlyWritten() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject.getAsString() == myString) {
        // Do something
      }
  }
}
Morał jest chyba taki, że bazujesz tylko na NSObject tam, gdzie naprawdę musisz!
 13
Author: Pete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 09:11:05

Zgodnie z odniesieniem do języka, nie ma wymogu, aby klasy podklasowały dowolną standardową klasę główną, więc możesz dołączyć lub pominąć superklasę w razie potrzeby.

Zauważ, że pominięcie superklasy z deklaracji klasy, nie przypisuje implicit base superclass jakiegokolwiek rodzaju. Definiuje klasę bazową, która stanie się korzeniem niezależnej hierarchii klas.

From the language reference:

Klasy Swift nie dziedziczą z uniwersalnego klasa podstawowa. Zajęcia ty definiowanie bez określania klasy nadrzędnej automatycznie staje się bazą klasy, na których możesz budować.

Próba odniesienia się super z klasy bez klasy super (tj. klasy bazowej) spowoduje błąd w czasie kompilacji

'super' members cannot be referenced in a root class
 11
Author: Cezar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-05 10:29:45

Uważam, że zdecydowana większość danych Swift nie będzie objc. Tylko te części, które muszą komunikować się z infrastrukturą celu C, zostaną wyraźnie oznaczone jako takie.

W jakim stopniu introspekcja runtime zostanie dodana do języka, Nie wiem. Przechwytywanie metody będzie możliwe tylko wtedy, gdy metoda wyraźnie na to pozwala. To jest moje przypuszczenie, ale tylko projektanci języka w Apple naprawdę wiedzą, dokąd naprawdę zmierzają.

 1
Author: Analog File,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-05 10:25:53

Poniższy tekst jest skopiowany z ebooka Swift firmy Apple i daje odpowiednią odpowiedź na twoje pytanie:

Definiowanie klasy bazowej

Każda klasa, która nie dziedziczy z innej klasy, jest znana jako klasa bazowa.

Klasy Swift nie dziedziczą po uniwersalnej klasie bazowej. Klasy definiowane bez określania klasy nadrzędnej automatycznie stają się klasami bazowymi, na których można budować.


Odniesienie

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251
 0
Author: wottpal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-05 10:26:55

To normalne. Spójrz na cele projektowe Swift: celem jest zniknięcie ogromnych klas problemów programistycznych. Metoda swizzling prawdopodobnie nie jest jedną z rzeczy, które chcesz zrobić z Swift.

 -4
Author: gnasher729,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-05 10:22:11