Estou começando a aprender Swift e tenho acompanhado as muito boas palestras em vídeo da Universidade de Stanford no YouTube. Aqui está um link, se você estiver interessado ou ajudar (embora não seja necessário entender o meu problema):
Desenvolvendo aplicativos iOS 8 com Swift - 2. Mais Xcode e Swift, MVC
Enquanto seguia as palestras, cheguei a um ponto em que (até onde eu sabia) meu código era idêntico ao código do vídeo, mas no meu sistema recebi um erro do compilador. Após várias tentativas e erros, consegui reduzir meu código para dois exemplos, um dos quais gera um erro, o outro ou o que não, mas não tenho idéia do que está realmente causando o erro ou como resolvê-lo.
O código que cria o erro é:
import UIKit
class BugViewController: UIViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
Isso cria o seguinte erro do compilador:
Método 'execute' com o seletor de Objective-C 'execute:' entra em conflito com a declaração anterior com o mesmo seletor de Objective-C
Simplesmente removendo a subclasse de UIViewController, o código compila:
import UIKit
class BugViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
Algumas outras informações que podem ou não ser relevantes:
- Eu atualizei recentemente para Yosemite.
- Quando instalei o Xcode, acabei com uma versão beta (versão 6.3 (6D543q)) porque (se bem me lembro) era a versão que eu precisava executar na minha versão do OS X.
Eu meio que espero que isso seja um bug no compilador porque, caso contrário, isso não faz sentido para mim. Qualquer ajuda recebida com gratidão!
Respostas:
O Objective-C não suporta sobrecarga de método, você deve usar um nome de método diferente. Quando você herdou o UIViewController, herdou o NSObject e tornou a classe interopável para Obj-C. O Swift, por outro lado, suporta sobrecarga, é por isso que funciona quando você remove a herança.
fonte
UIFont
todos os dias.Eu também estou fazendo o curso Standford e fiquei preso aqui por um longo tempo também, mas depois de algumas pesquisas, encontrei algo daqui: notas de versão do Xcode e ele mencionou algo abaixo:
o que eu fiz foi apenas adicionar "private" na frente do método de substituição como este:
fonte
Como já foi respondido, o ObjC não suporta sobrecarga de método (dois métodos com o mesmo nome) e no swift 2 no Xcode 7 existem duas opções para resolver esse tipo de problema. Uma opção é renomear o método usando o atributo:
@objc(newNameMethod:)
Outra opção para resolver esse problema no Xcode 7+ é aplicar
@nonobjc
atributo a qualquer método, subscrito ou inicializadorfonte
O problema é que
UIViewController
é uma@objc
classe. Ao herdar deUIViewController
,BugViewController
também é uma@objc
classe.Isso significa que ele deve estar em conformidade com as regras dos seletores de Objective-C (o nome de um método). Os métodos
func perform(operation: (Double) -> Double)
efunc perform(operation: (Double, Double) -> Double)
ambos têm o mesmo seletor@selector(perform:)
. Isso não é permitido.Para resolver isso, use nomes diferentes: como
func perform1(operation: (Double) -> Double)
efunc perform2(operation: (Double, Double) -> Double)
.Eu acho que a melhor maneira de lidar com isso é dar aos seus
perform()
métodos nomes mais descritivos. O que esses métodos fazem? Como eles mudam o estado do controlador de exibição? Observe os outrosUIViewController
métodos para ter uma idéia do estilo de nomeação de métodos ou leia Nomes de métodos devem ser expressivos e exclusivos em uma classefonte
Em https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html em "Xcode 6.3 Release Notes" -> "Swift Language Changes", você encontra
fonte
Eu recebi o mesmo erro devido a ter dois métodos com a mesma assinatura Obj-C:
Eu não queria marcar um deles como @nonobjc devido à possibilidade de consequências imprevistas no tempo de execução. (Alguém pode me corrigir se não houver possibilidade)
Resolvi usando o recurso de nome de parâmetro externo do Swift (tornei o nome externo igual ao nome local) para o segundo método, que altera efetivamente a assinatura do método Obj-c:
fonte