Il membro dell'istanza non può essere utilizzato sul tipo


139

Ho la seguente classe:

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

La compilazione non riesce con il messaggio:

Il membro dell'istanza 'categoriePerPage' non può essere utilizzato sul tipo 'ReportView'

Cosa significa questo?


12
Immaginando che dichiarerai una proprietà calcolata numPagespiuttosto che una chiusura, elimina il segno uguale:var numPages: Int { return categoriesPerPage.count }
vadian

1
Può essere spiegato in modo più preciso cosa significa questo messaggio di errore? Lo vedo in un contesto completamente diverso.
William Entriken,

2
Quando dichiari un blocco nell'ambito della classe, come sopra, sei limitato a ciò che è disponibile nel tipo. Non hai accesso a nessun membro dell'istanza.
Aderstedt,

Nota: il messaggio di errore è simile a quello visualizzato quando si tenta di creare una variabile lazy ma si è dimenticato uno dei requisiti . Nel tuo caso non vuoi una variabile pigra poiché categoriesPerPageè definita come varanziché let.
Senso

1
Rimuovi = da: var numPagine: Int =
andrewz

Risposte:


132

Hai solo un errore di sintassi quando dici = {return self.someValue}. Non =è necessario.

Uso :

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

}

se vuoi ottenere solo tu puoi scrivere

var numPages: Int {
     return categoriesPerPage.count
}

con il primo modo puoi anche aggiungere osservatori come set willSet&didSet

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

permettendo di usare = operatorcome setter

myObject.numPages = 5

1
Oops, ho perso il segno uguale. Grazie.
Aderstedt,

Stai dicendo che stai per inizializzare categoriesPerPage, che è un array a 2 dim con vquale è Int?
Dan,

@ Dan Your'e destra, L'esempio è solo per dimostrare setad esempio, di partecipazione al corso non è possibile assegnare intin[int]
Daniel Krom

Fatto questo un milione di volte e mancava ancora il segno extra = :)
Alexandre G,

non hai bisogno della famiglia del punto e virgola
Peter Schorn,

51

Per chiunque altro si imbatta in questo, assicurati di non tentare di modificare la classe anziché l'istanza! (a meno che tu non abbia dichiarato la variabile come statica)

per esempio.

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

instanceOfMyClass.variable = 'Foo' // Right!

5
Questa è la differenza tra staticvariabile e instancevariabile, MyClass.variableè valida se la dichiarerai come variabile statica (condivisa tra tutte le istanze)
Daniel Krom,

Questo era il mio problema Trovo strano che XCode decida di mettere la classe al primo posto tra le opzioni di completamento automatico prima di un'istanza con un nome simile quando il contesto sembra puntarmi decisamente sull'istanza piuttosto che sulla classe stessa. E nei casi in cui la tua istanza differisce solo per caso, può essere difficile notare che hai scelto la classe piuttosto che l'istanza che intendevi. Grazie!
LeftOnTheMoon

19

Sta dicendo che hai una variabile di istanza (var è visibile / accessibile solo quando hai un'istanza di quella classe) e stai provando a usarla nel contesto di un ambito statico (metodo di classe).

È possibile rendere la variabile di istanza una variabile di classe aggiungendo l'attributo statico / classe.

Istanzia un'istanza della tua classe e chiami il metodo dell'istanza su quella variabile.


Nel mio caso, ho provato a usare una variabile di istanza nel blocco di completamento chiamato dopo che era stata inizializzata un'istanza di un'altra classe. Naturalmente, un init è una funzione di classe e dichiarare la variabile di istanza come statica ha risolto il problema.
Reinhard Männer,

8

Un altro esempio è che hai classe come:

@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
    }
}

otterrai anche lo stesso tipo di errore come:

instance member x cannot be used on type x. 

È perché assegni il tuo metodo con la parola chiave "class" (che rende il tuo metodo un metodo di tipo) e usi come:

Album.getCurrentlyPlayingSongLyric(duration: 5)

ma chi ha impostato prima la variabile playingSong? Ok. Non dovresti usare la parola chiave class per quel caso:

 // ...

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

 // ...

Ora sei libero di andare.


8

A volte Xcode quando sostituisce i metodi aggiunge class funcanziché semplicemente func. Quindi nel metodo statico non è possibile visualizzare le proprietà dell'istanza. È molto facile trascurarlo. Quello era il mio caso.

inserisci qui la descrizione dell'immagine


Ah grazie! Ho passato molto tempo a capire perché non avevo ricevuto alcun suggerimento di completamento automatico dei membri dell'istanza in Xcode. Sembra un bug, invierò un radar con Apple 👍🏽
Apoorv Khatreja il

3

Il tuo problema iniziale era:

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

Il membro dell'istanza 'categoriePerPage' non può essere utilizzato sul tipo 'ReportView'

i post precedenti indicano correttamente, se si desidera una proprietà calcolata , il =segno è errato.

Ulteriore possibilità di errore:

Se il tuo intento era "Impostazione di un valore di proprietà predefinito con una chiusura o una funzione" , devi anche modificarlo leggermente. (Nota: questo esempio non era ovviamente destinato a farlo)

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

Invece di rimuovere il =, aggiungiamo ()per indicare una chiusura di inizializzazione predefinita. (Questo può essere utile durante l'inizializzazione del codice UI, per tenerlo tutto in un unico posto.)

Tuttavia, si verifica lo stesso errore esatto :

Il membro dell'istanza 'categoriePerPage' non può essere utilizzato sul tipo 'ReportView'

Il problema sta provando a inizializzare una proprietà con il valore di un'altra. Una soluzione è creare l'inizializzatore lazy. Non verrà eseguito fino all'accesso al valore.

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

ora il compilatore è felice!


0

Continuavo a ricevere lo stesso errore nonostante la creazione della variabile static. Soluzione: Clean Build, Clean Derived Data, Restart Xcode. O scorciatoia Cmd + Maiusc + Alt + K

UserNotificationCenterWrapper.delegate = self

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

0

Nel caso in cui qualcuno abbia davvero bisogno di una chiusura del genere, può essere fatto nel modo seguente:

var categoriesPerPage = [[Int]]()
var numPagesClosure: ()->Int {
    return {
        return self.categoriesPerPage.count
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.