Classe base nativa rápida ou NSObject

Eu testei alguns isa swizzling com Swift, e descobri que só funciona quando o NSObject é uma superclass (direta ou superior), ou usando a decoração ‘@objc’. Caso contrário, ele seguirá um estilo de despacho estático e vtable, como o C ++.

É normal definir uma class Swift sem uma class base Cocoa / NSObject? Se estou preocupado, isso significa renunciar a grande parte do dinamismo de Objective-C, como a interceptação de methods e a introspecção em tempo de execução.

O comportamento dynamic do tempo de execução está no centro dos resources, como observadores de propriedade, Dados Principais, Programação Orientada a Aspectos , Mensagens de Pedidos Superiores , estruturas analíticas e de registro e assim por diante.

A invocação do estilo de método do Objective-C adiciona cerca de 20 operandos de código de máquina a uma chamada de método, portanto, em determinadas situações ( muitas chamadas restritas a methods com corpos pequenos ), o despacho estático e vtable do estilo C ++ pode ter melhor desempenho.

Mas, dada a regra geral 95-5 ( 95% dos ganhos de desempenho vêm do ajuste de 5% do código ), não faz sentido começar com os poderosos resources dynamics e endurecer onde necessário?

Classes Swift que são subclasss de NSObject:

  • são classs Objective-C
  • use objc_msgSend() para chamadas para (a maioria de) seus methods
  • Fornecer metadados de tempo de execução do Objective-C para (a maioria) de suas implementações de método

Classes Swift que não são subclasss de NSObject:

  • são classs Objective-C, mas implementam apenas um punhado de methods para compatibilidade com NSObject
  • não use objc_msgSend() para chamadas para seus methods (por padrão)
  • não fornecem metadados de tempo de execução do Objective-C para suas implementações de método (por padrão)

A subclass de NSObject no Swift fornece a flexibilidade de tempo de execução do Objective-C, mas também o desempenho do Objective-C. Evitar o NSObject pode melhorar o desempenho se você não precisar da flexibilidade do Objective-C.

Editar:

Com o Xcode 6 beta 6, o atributo dynamic é exibido. Isso nos permite instruir o Swift que um método deve usar o despacho dynamic e, portanto, oferecer suporte à interceptação.

 public dynamic func foobar() -> AnyObject { } 

Eu também achei que, se baseando uma class Swift no NSObject, eu vi algum comportamento inesperado em tempo de execução que poderia ocultar os erros de codificação. Aqui está um exemplo.

Neste exemplo, onde não baseamos em NSObject, o compilador localiza corretamente o erro em testIncorrect_CompilerShouldSpot, relatando “… ‘MyClass’ não é conversível em ‘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 } } } 

Neste exemplo, onde nos baseamos em NSObject , o compilador não detecta o erro em 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 } } } 

Eu acho que a moral é baseada apenas no NSObject, onde você realmente precisa!

De acordo com a referência de idioma, não há requisito para classs subclassificarem qualquer class raiz padrão, portanto, você pode include ou omitir uma superclass conforme necessário.

Note que omitir uma superclass da declaração de class, não atribui uma superclass base implícita de qualquer tipo. Ele define uma class base, que efetivamente se tornará a raiz de uma hierarquia de classs independente.

A partir da referência da linguagem:

Classes Swift não herdam de uma class base universal. As classs que você define sem especificar uma superclass automaticamente se tornam classs base para você construir.

Tentando fazer referência a super de uma class sem uma superclass (isto é, uma class base) resultará em um erro de tempo de compilation

 'super' members cannot be referenced in a root class 

Eu acredito que a grande maioria dos dados do Swift não será objc . Apenas as partes que precisam se comunicar com a infraestrutura do Objetivo C serão explicitamente marcadas como tal.

Em que medida a introspecção em tempo de execução será adicionada à linguagem, eu não sei. A interceptação de methods provavelmente só será possível se o método permitir isso explicitamente. Este é o meu palpite, mas apenas os designers de linguagem da Apple sabem realmente para onde estão indo.

O seguinte é copiado do Swift-eBook da Apple e dá uma resposta adequada à sua pergunta:

Definindo uma Classe Base

Qualquer class que não herda de outra class é conhecida como uma class base.

Classes Swift não herdam de uma class base universal. As classs que você define sem especificar uma superclass automaticamente se tornam classs base para você construir.

Referência

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251

É normal. Olhe para os objectives de design do Swift: O objective é fazer com que grandes classs de problemas de programação desapareçam. Swizzling método provavelmente não é uma das coisas que você quer fazer com Swift.