Cuando estoy declarar las variables como weak en Swift, a veces me sale el mensaje de error de Xcode:

‘débil’ sólo puede ser aplicado a la clase y la clase de obligado tipos de protocolo

Me preguntaba por qué la palabra clave weak sólo puede aplicarse a clase y la clase de obligado tipos de protocolo? ¿Cuál es la razón detrás de ella?

  • weak sólo es relevante para el recuento de referencias y sólo las clases son de referencia contado
InformationsquelleAutor Thor | 2016-08-09

9 Comentarios

  1. 56

    weak es un torneo de clasificación para los tipos de referencia (en contraposición a los tipos de valor, tales como structs y construido en los tipos de valor).

    Los tipos de referencia permiten tener múltiples referencias al mismo objeto. El objeto se desasignan cuando la última referencia fuerte deja que hacen referencia a él (referencias débiles no cuentan).

    Tipos de valor, por otro lado, son asignados por copia. Conteo de referencia no se aplica, por lo que weak modificador no tiene sentido con ellos.

  2. 123

    Una razón común de este error es que ha declarado que el propio protocolo, pero se olvidó de heredar de NSObjectProtocol:

    protocol PenguinDelegate: NSObjectProtocol {
        func userDidTapThePenguin()
    }
    
    class MyViewController: UIViewController {
        weak var delegate: PenguinDelegate?
    }

    El código anterior le dará el error si se olvida de heredar de NSObjectProtocol. La razón es que weak sólo tiene sentido para los tipos de referencia (clases). El compilador menos nervioso indicando claramente que la PenguinDelegate está pensado para las clases, y no de los tipos de valor.

    • ¿cuál es la ventaja de la herencia de NSObjectProtocol? Mis propios delegados no hacerlo y no he encontrado ningún problema en mis usos
    • Referencias débiles son válidos sólo en las clases. Heredando de NSObjectProtocol tu garantizando al compilador que el protocolo sólo será utilizada para las clases (y no para las enumeraciones, etc.).
    • ¿Cuál es la ventaja de garantizar que para el compilador? No es más fácil simplemente no heredan de NSObjectProtocol? Para que usted no tenga que lidiar con la adición de la weak modificador.
    • Sí, funciona. Pero no sé por qué. weak es un torneo de clasificación para los tipos de referencia, no tiene sentido con los tipos de valor debido a los tipos de valor que no puede ser débil, por definición. Un protocolo puede ser adoptado por los tipos de referencia y de los tipos de valor. Así que usted debe limitar a ser implementado solo por los tipos de referencia: protocol PenguinDelegate: class { } Aquí, que están limitando el protocolo que se aplicará sólo al NSObjectProtocols, cuyos son los tipos de referencia demasiado, esa es la razón de por qué funciona.
    • Uso protocol PenguinDelegate: class que no depende de un Objetivo-tiempo de ejecución de C, pero todavía se soluciona el problema.
  3. 60
    protocol PenguinDelegate: class {
        func userDidTapThePenguin()
    }
    
    class MyViewController: UIViewController {
        weak var delegate: PenguinDelegate?
    }

    Si el tipo de clase después de su protocolo que funciona tan bien y parece más apropiado para NSObjectProtocol.

    • Me siento como la combinación de esto y la respuesta de @dasblinkenlight totalmente responder a esta pregunta. dasblinkenlight explicó por qué el mensaje de error se muestra y explica cómo lograr lo que probablemente estaban tratando de hacer como un desarrollador.
  4. 12

    Bien sólo en caso de que otra persona piensa que tiene todo lo correcto en el código como yo, compruebe que no haya erróneamente sustituida la : por un =.

    Aquí es lo que yo tenía. Fue también me da el mismo error de antes:

    protocol PenguinDelegate: class {
        func userDidTapThePenguin()
    }
    
    class MyViewController: UIViewController {
        weak var delegate = PenguinDelegate?
    }

    Pero la forma correcta es:

    protocol PenguinDelegate: class {
        func userDidTapThePenguin()
    }
    
    class MyViewController: UIViewController {
        weak var delegate: PenguinDelegate?
    }

    ¿Ves la diferencia? Me tomó un tiempo para ver que había un signo igual en lugar de un signo de dos puntos. También se nota que me hizo llegar otro de los errores de la misma línea para que yo había decidido que mi primer error parecer los más propensos a ser el verdadero problema :

    weak sólo puede ser aplicado a la clase y la clase de obligado tipos de protocolo

    :-<

  5. 2

    weak es para el ARC(Automatic Reference Counting). No significa la adición de recuento de referencia. Por lo que sólo funciona para Class. Y en Swift, usted va a obtener valor opcional para la seguridad.

  6. 2

    Me encuentro en un caso donde usted puede incluso tener un tipo de clase, pero todavía recibe este mensaje de error.

    Por ejemplo,

    class MyVC: UIViewController {
       var myText: UITextView = {
          [weak self]
          let text = UITextView()
          //some codes using self
          return text
       }()
    }

    Aquí un UITextView objeto es devuelto de un bloque anónimo como la inicialización de var myText. Tengo el mismo tipo de mensaje de error. Para resolver el problema, el var tiene que ser marcado como lazy:

    class MyVC: UIViewController {
       lasy var myText: UITextView = {
          [weak self]
          let text = UITextView()
          //some codes using self
          return text
       }()
    }
  7. 1

    Traté de capturar la Cadena y de la Matriz con las propiedades de un cierre. Tengo estos errores:

    ‘débil’ sólo puede ser aplicado a la clase y la clase de obligado tipos de protocolo, no ‘[String]’

    ‘débil’ sólo puede ser aplicado a la clase y la clase de obligado tipos de protocolo, no ‘Cadena’

    He jugado un rato en el patio de recreo, y resultó que la captura de uno mismo es suficiente para estos tipos.

  8. 1

    ¿Por qué la palabra Estaba usando el objetivo de la clase C en swift para scrolView. He creado IBOutlet de que el desplazamiento de la vista. Y al compilar este código de error comenzó a mostrar.

    Así que para solucionar este tipo de problema, importar de que clase en el puente de encabezado

    de importación «YourClass.h»

    Yo estaba usando Xcode 9.2 con swift 3.2

Dejar respuesta

Please enter your comment!
Please enter your name here