El miembro de instancia no se puede usar en el tipo

139

Tengo la siguiente clase:

class ReportView: NSView {  
    var categoriesPerPage = [[Int]]()
    var numPages: Int = { return categoriesPerPage.count }
}

La compilación falla con el mensaje:

El miembro de instancia 'categoriesPerPage' no se puede usar en el tipo 'ReportView'

¿Qué significa esto?

Aderstedt
fuente
12
Adivinando que va a declarar una propiedad calculada en numPageslugar de un cierre, elimine el signo igual:var numPages: Int { return categoriesPerPage.count }
vadian
1
¿Puede explicarse más a fondo exactamente qué significa este mensaje de error? Lo estoy viendo en un contexto completamente diferente.
William Entriken
2
Cuando declaras un bloque en el alcance de la clase, como el anterior, estás limitado a lo que está disponible en el tipo. No tiene acceso a ningún miembro de la instancia.
Aderstedt
Nota: El mensaje de error es similar al que aparece al intentar crear una variable perezosa, pero olvidó uno de los requisitos . En su caso, no desea una variable perezosa ya que categoriesPerPagese define como en varlugar de let.
Senseful
1
Eliminar = de: var numPages: Int =
andrewz

Respuestas:

132

Solo tienes un error de sintaxis al decir = {return self.someValue}. El =no es necesario.

Utilizar :

var numPages: Int {
    get{
        return categoriesPerPage.count
    }

}

si quieres obtener solo puedes escribir

var numPages: Int {
     return categoriesPerPage.count
}

con la primera forma también puedes agregar observadores como set willSet&didSet

var numPages: Int {
    get{
        return categoriesPerPage.count
    }
    set(v){
       self.categoriesPerPage = v
    }
}

permitiendo usar = operatorcomo setter

myObject.numPages = 5
Daniel Krom
fuente
1
Vaya, me perdí el signo igual. Gracias.
Aderstedt
¿Estás diciendo que vas a inicializar categoriesPerPage, que es una matriz de 2 dim con vcuál es Int?
Dan
@ Dan Your'e derecha, el ejemplo es sólo para demostrar setejemplo, de curso no se puede asignar inten[int]
Daniel Krom
Hecho esto un millón de veces y aún así perder el extra signo = :)
Alexandre G
no necesitas el punto y coma fam
Peter Schorn
51

¡Para cualquier otra persona que se encuentre con esto, asegúrese de no intentar modificar la clase en lugar de la instancia! (a menos que haya declarado la variable como estática)

p.ej.

MyClass.variable = 'Foo' // WRONG! - Instance member 'variable' cannot be used on type 'MyClass'

instanceOfMyClass.variable = 'Foo' // Right!
Derek
fuente
55
Esta es la diferencia entre staticvariable y instancevariable, MyClass.variablees válida si la declaras como variable estática (compartida entre todas las instancias)
Daniel Krom
Este fue mi problema. Me resulta un poco extraño cuando XCode decide poner la clase primero en las opciones de autocompletar antes de una instancia con un nombre similar cuando el contexto parece apuntarme definitivamente a usar la instancia en lugar de la clase misma. Y en los casos en que su instancia solo difiere según el caso, puede ser difícil notar que eligió la clase en lugar de la instancia que deseaba. ¡Gracias!
LeftOnTheMoon
19

Está diciendo que tiene una variable de instancia (la var solo es visible / accesible cuando tiene una instancia de esa clase) y está tratando de usarla en el contexto de un ámbito estático (método de clase).

Puede convertir su variable de instancia en una variable de clase agregando atributos estáticos / de clase.

Instancia una instancia de su clase y llama al método de instancia en esa variable.

Vlad
fuente
En mi caso, intenté usar una variable de instancia en el bloque de finalización llamado después de que se haya inicializado una instancia de otra clase. Por supuesto, un init es una función de clase, y declarar la variable de instancia como estática resolvió el problema.
Reinhard Männer
8

Otro ejemplo es que tienes una clase como:

@obc class Album: NSObject {
    let name:String
    let singer:Singer
    let artwork:URL
    let playingSong:Song


    // ...

    class func getCurrentlyPlayingSongLyric(duration: Int = 0) -> String {
        // ...
       return playingSong.lyric
    }
}

también obtendrá el mismo tipo de error como:

instance member x cannot be used on type x. 

Es porque asigna su método con la palabra clave "class" (que hace que su método sea un método de tipo) y usa like:

Album.getCurrentlyPlayingSongLyric(duration: 5)

¿Pero quién estableció la variable playingSong antes? Okay. No debe usar la palabra clave de clase para ese caso:

 // ...

 func getCurrentlyPlayingSongLyric(duration: Int = 0) -> String {
        // ...
       return playingSong.lyric
 }

 // ...

Ahora eres libre de irte.

mgyky
fuente
8

A veces, Xcode cuando anula los métodos agrega en class funclugar de solo func. Luego, en el método estático, no puede ver las propiedades de la instancia. Es muy fácil pasarlo por alto. Ese fue mi caso.

ingrese la descripción de la imagen aquí

milczi
fuente
¡Ah gracias! Pasé mucho tiempo descubriendo por qué no recibía ninguna de las sugerencias de autocompletado de miembros de la instancia en Xcode. Esto parece un error, archivaré un radar con Apple Apo
Apoorv Khatreja
3

Su problema inicial fue:

class ReportView: NSView {
  var categoriesPerPage = [[Int]]()
  var numPages: Int = { return categoriesPerPage.count }
}

El miembro de instancia 'categoriesPerPage' no se puede usar en el tipo 'ReportView'

las publicaciones anteriores señalan correctamente, si desea una propiedad calculada , el =signo es erróneo.

Posibilidad adicional de error:

Si su intención era "Establecer un valor de propiedad predeterminado con un cierre o función" , también necesita cambiarlo ligeramente. (Nota: este ejemplo obviamente no estaba destinado a hacer eso)

class ReportView: NSView {
  var categoriesPerPage = [[Int]]()
  var numPages: Int = { return categoriesPerPage.count }()
}

En lugar de eliminar el =, agregamos ()para denotar un cierre de inicialización predeterminado. (Esto puede ser útil al inicializar el código de la interfaz de usuario, para mantenerlo todo en un solo lugar).

Sin embargo, se produce exactamente el mismo error :

El miembro de instancia 'categoriesPerPage' no se puede usar en el tipo 'ReportView'

El problema está tratando de inicializar una propiedad con el valor de otra. Una solución es hacer el inicializador lazy. No se ejecutará hasta que se acceda al valor.

class ReportView: NSView {
  var categoriesPerPage = [[Int]]()
  lazy var numPages: Int = { return categoriesPerPage.count }()
}

¡ahora el compilador está feliz!

bshirley
fuente
0

Seguí recibiendo el mismo error a pesar de hacer la variable static. Solución: construcción limpia, datos derivados limpios, reinicio de Xcode. O atajo Cmd + Shift + Alt + K

UserNotificationCenterWrapper.delegate = self

public static var delegate: UNUserNotificationCenterDelegate? {
        get {
            return UNUserNotificationCenter.current().delegate
        }
        set {
            UNUserNotificationCenter.current().delegate = newValue
        }
    }
Naishta
fuente
0

En caso de que alguien realmente necesite un cierre así, se puede hacer de la siguiente manera:

var categoriesPerPage = [[Int]]()
var numPagesClosure: ()->Int {
    return {
        return self.categoriesPerPage.count
    }
}
algrid
fuente