Instanzmitglied kann nicht für Typ verwendet werden

138

Ich habe folgende Klasse:

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

Die Kompilierung schlägt mit der Meldung fehl:

Das Instanzmitglied 'categoryPerPage' kann nicht für den Typ 'ReportView' verwendet werden.

Was bedeutet das?

Aderstedt
quelle
12
Wenn Sie eine berechnete Eigenschaft numPagesanstelle eines Abschlusses deklarieren, löschen Sie das Gleichheitszeichen:var numPages: Int { return categoriesPerPage.count }
vadian
1
Kann man bitte genauer erklären, was diese Fehlermeldung bedeutet? Ich sehe es in einem ganz anderen Kontext.
William Entriken
2
Wenn Sie wie oben einen Block im Klassenbereich deklarieren, sind Sie auf das beschränkt, was im Typ verfügbar ist. Sie haben keinen Zugriff auf Instanzmitglieder.
Aderstedt
Hinweis: Die Fehlermeldung ähnelt der, die Sie erhalten, wenn Sie versuchen , eine verzögerte Variable zu erstellen, aber eine der Anforderungen vergessen haben . In Ihrem Fall möchten Sie keine Lazy-Variable, da categoriesPerPagedefiniert als varanstelle von let.
Sinnvoll
1
Entfernen = von: var numPages: Int =
andrewz

Antworten:

131

Sie haben nur einen Syntaxfehler, wenn Sie sagen = {return self.someValue}. Das =wird nicht benötigt.

Verwenden :

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

}

wenn du nur bekommen willst kannst du schreiben

var numPages: Int {
     return categoriesPerPage.count
}

Mit der ersten Möglichkeit können Sie auch Beobachter als set willSet& hinzufügendidSet

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

so dass die Verwendung = operatorals setter

myObject.numPages = 5
Daniel Krom
quelle
1
Hoppla, ich habe das Gleichheitszeichen verpasst. Vielen Dank.
Aderstedt
Sie sagen, Sie werden initialisieren categoriesPerPage, welches 2-Dim-Array mit vwelchem ​​Int?
Dan
@ Dan Your'e rechts ist das Beispiel nur zeigen , setbeispielsweise von-Kurs können Sie nicht zuweisen intin[int]
Daniel Krom
Dies millionenfach getan und trotzdem das Extra = Zeichen verpasst :)
Alexandre G
Sie brauchen das Semikolon fam nicht
Peter Schorn
51

Für alle anderen, die darauf stoßen, stellen Sie sicher, dass Sie nicht versuchen, die Klasse und nicht die Instanz zu ändern! (es sei denn, Sie haben die Variable als statisch deklariert)

z.B.

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

instanceOfMyClass.variable = 'Foo' // Right!
Derek
quelle
5
Dies ist der Unterschied zwischen staticVariable und instanceVariable, MyClass.variableist gültig, wenn Sie es als statische Variable deklarieren (gemeinsam von allen Instanzen)
Daniel Krom
Das war mein Problem. Ich finde es seltsam, wenn XCode beschließt, die Klasse in den Optionen für die automatische Vervollständigung vor einer Instanz mit ähnlichem Namen an die erste Stelle zu setzen, wenn der Kontext darauf hinzudeuten scheint, dass ich die Instanz definitiv anstelle der Klasse selbst verwende. Und in Fällen, in denen sich Ihre Instanz nur von Fall zu Fall unterscheidet, kann es schwierig sein zu bemerken, dass Sie die Klasse und nicht die von Ihnen beabsichtigte Instanz ausgewählt haben. Vielen Dank!
LeftOnTheMoon
19

Es heißt, Sie haben eine Instanzvariable (die Variable ist nur sichtbar / zugänglich, wenn Sie eine Instanz dieser Klasse haben) und Sie versuchen, sie im Kontext eines statischen Bereichs (Klassenmethode) zu verwenden.

Sie können Ihre Instanzvariable zu einer Klassenvariablen machen, indem Sie das Attribut static / class hinzufügen.

Sie instanziieren eine Instanz Ihrer Klasse und rufen die Instanzmethode für diese Variable auf.

Vlad
quelle
In meinem Fall habe ich versucht, eine Instanzvariable im Abschlussblock zu verwenden, der aufgerufen wurde, nachdem eine Instanz einer anderen Klasse initialisiert wurde. Natürlich ist ein init eine Klassenfunktion, und das Deklarieren der Instanzvariablen als statisch hat das Problem gelöst.
Reinhard Männer
8

Ein anderes Beispiel ist, Sie haben Klasse wie:

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

Sie erhalten auch die gleiche Art von Fehler wie:

instance member x cannot be used on type x. 

Dies liegt daran, dass Sie Ihrer Methode das Schlüsselwort "class" zuweisen (wodurch Ihre Methode zu einer Typmethode wird) und Folgendes verwenden:

Album.getCurrentlyPlayingSongLyric(duration: 5)

Aber wer hat die Variable playSong schon einmal gesetzt? OK. In diesem Fall sollten Sie kein Klassenschlüsselwort verwenden:

 // ...

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

 // ...

Jetzt können Sie gehen.

mgyky
quelle
7

Manchmal fügt Xcode beim Überschreiben von Methoden class funcstatt nur hinzu func. In der statischen Methode können Sie dann keine Instanzeigenschaften sehen. Es ist sehr leicht zu übersehen. Das war mein Fall.

Geben Sie hier die Bildbeschreibung ein

milczi
quelle
Ah, Danke! Ich habe lange herausgefunden, warum ich in Xcode keine Vorschläge zur automatischen Vervollständigung von Instanzmitgliedern erhalten habe. Dies scheint ein Fehler zu sein, ich werde ein Radar bei Apple einreichen Ap
Apoorv Khatreja
3

Ihr anfängliches Problem war:

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

Das Instanzmitglied 'categoryPerPage' kann nicht für den Typ 'ReportView' verwendet werden.

In früheren Beiträgen wurde korrekt darauf hingewiesen, dass das Vorzeichen fehlerhaft ist , wenn Sie eine berechnete Eigenschaft wünschen =.

Zusätzliche Fehlermöglichkeit:

Wenn Sie beabsichtigen, "einen Standardeigenschaftswert mit einem Abschluss oder einer Funktion festzulegen" , müssen Sie ihn ebenfalls nur geringfügig ändern. (Hinweis: Dieses Beispiel war offensichtlich nicht dazu gedacht)

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

Anstatt das zu entfernen =, fügen wir hinzu (), um einen Standard-Initialisierungsabschluss zu kennzeichnen. (Dies kann beim Initialisieren von UI-Code hilfreich sein, um alles an einem Ort zu speichern.)

Es tritt jedoch genau der gleiche Fehler auf:

Das Instanzmitglied 'categoryPerPage' kann nicht für den Typ 'ReportView' verwendet werden.

Das Problem besteht darin, eine Eigenschaft mit dem Wert einer anderen zu initialisieren. Eine Lösung besteht darin, den Initialisierer zu erstellen lazy. Es wird erst ausgeführt, wenn auf den Wert zugegriffen wird.

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

jetzt ist der compiler glücklich!

bshirley
quelle
0

Ich habe immer wieder den gleichen Fehler bekommen, obwohl ich die Variable gemacht habe static. Lösung: Clean Build, Abgeleitete Daten bereinigen, Xcode neu starten. Oder Verknüpfung Cmd + Umschalt + Alt + K.

UserNotificationCenterWrapper.delegate = self

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

Nur für den Fall, dass jemand wirklich einen solchen Verschluss benötigt , kann dies folgendermaßen geschehen:

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