Estoy empezando a aprender Swift y he seguido las muy buenas conferencias en video de la Universidad de Stanford en YouTube. Aquí hay un enlace si está interesado o ayuda (aunque no es necesario que comprenda mi problema):
Desarrollo de aplicaciones iOS 8 con Swift - 2. Más Xcode y Swift, MVC
Mientras seguía las conferencias llegué a un punto en el que (por lo que podía ver) mi código era idéntico al código del video, pero en mi sistema recibí un error del compilador. Después de muchas pruebas y errores, he logrado reducir mi código a dos ejemplos, uno de los cuales genera un error, el otro o el que no, pero no tengo idea de qué está causando el error o cómo resolverlo.
El código que crea el error es:
import UIKit
class BugViewController: UIViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
Esto crea el siguiente error del compilador:
Método 'perform' con el selector Objective-C 'perform:' entra en conflicto con la declaración anterior con el mismo selector Objective-C
Simplemente eliminando la subclasificación de UIViewController, el código compila:
import UIKit
class BugViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
Otra información que puede o no ser relevante:
- Recientemente he actualizado a Yosemite.
- Cuando instalé Xcode, terminé con una versión Beta (Versión 6.3 (6D543q)) porque (si no recuerdo mal) esta era la versión que necesitaba ejecutar en mi versión de OS X.
Estoy medio esperando que esto sea un error en el compilador porque de lo contrario esto no tiene ningún sentido para mí. Cualquier ayuda muy agradecida recibida!
Respuestas:
Objective-C no admite la sobrecarga de métodos, debe usar un nombre de método diferente. Cuando heredaste UIViewController, heredaste NSObject e hiciste la clase interopable con Obj-C. Swift, por otro lado, admite la sobrecarga, es por eso que funciona cuando elimina la herencia.
fuente
UIFont
todos los días.Yo mismo también estoy tomando el curso de Standford y me quedé atrapado aquí por mucho tiempo también, pero después de buscar, encontré algo desde aquí: notas de lanzamiento de Xcode y mencionó algo a continuación:
lo que hice fue agregar "privado" frente al método de anulación como este:
fuente
Como ya se ha respondido, ObjC no admite la sobrecarga de métodos (dos métodos con el mismo nombre) y en Swift 2 bajo Xcode 7 hay dos opciones para resolver este tipo de problemas. Una opción es renombrar el método usando el atributo:
@objc(newNameMethod:)
Otra opción para resolver este problema en Xcode 7+ es aplicar el
@nonobjc
atributo a cualquier método, subíndice o inicializador.fuente
El problema es
UIViewController
es una@objc
clase. Al heredar deUIViewController
,BugViewController
también es un@objc
clase.Esto significa que debe cumplir con las reglas de los selectores Objective-C (el nombre de un método). Los métodos
func perform(operation: (Double) -> Double)
yfunc perform(operation: (Double, Double) -> Double)
ambos tienen el mismo selector@selector(perform:)
. Esto no esta permitido.Para resolver esto, use diferentes nombres: me gusta
func perform1(operation: (Double) -> Double)
yfunc perform2(operation: (Double, Double) -> Double)
.Creo que la mejor manera de manejar esto es darle a sus
perform()
métodos nombres más descriptivos. ¿Qué hacen estos métodos? ¿Cómo cambian el estado del controlador de vista? Mire los otrosUIViewController
métodos para tener una idea del estilo de denominación de métodos, o lea Los nombres de métodos deben ser expresivos y únicos dentro de una clasefuente
En https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html en "Xcode 6.3 Release Notes" -> "Swift Language Changes" encontrará
fuente
Obtuve el mismo error debido a que tengo dos métodos con la misma firma Obj-C:
No quería marcar a uno de ellos como @nonobjc debido a la posibilidad de consecuencias imprevistas en el tiempo de ejecución. (Alguien puede corregirme si no hay posibilidad)
Lo resolvió usando la función de nombre de parámetro externo de Swift (hice el nombre externo igual que el nombre local) para el segundo método, que efectivamente cambia la firma del método Obj-c:
fuente