Элемент экземпляра не может использоваться по типу


139

У меня есть следующий класс:

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

Компиляция завершается с сообщением:

Элемент экземпляра categoryPerPage нельзя использовать для типа ReportView

Что это значит?


12
Предполагая, что вы собираетесь объявить вычисляемое свойство, numPagesа не замыкание, удалите знак равенства:var numPages: Int { return categoriesPerPage.count }
vadian

1
Можно ли объяснить более подробно, что именно означает это сообщение об ошибке? Я вижу это в совершенно другом контексте.
Уильям Энтрикен

2
Когда вы объявляете блок в области видимости класса, как описано выше, вы ограничены тем, что доступно в типе. У вас нет доступа ни к одному из участников.
Aderstedt

Примечание. Сообщение об ошибке аналогично сообщению, которое вы получаете при попытке создать переменную lazy, но забыли одно из требований . В вашем случае вам не нужна переменная типа lazy, поскольку categoriesPerPageона определена как varвместо let.
Чувственный

1
Удалить = из: var numPages: Int =
andrewz

Ответы:


132

У вас просто есть синтаксическая ошибка при произнесении = {return self.someValue}. =Не требуется.

Используйте:

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

}

если хочешь получить только можешь написать

var numPages: Int {
     return categoriesPerPage.count
}

первым способом вы также можете добавить наблюдателей как set willSet&didSet

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

позволяет использовать = operatorв качестве сеттера

myObject.numPages = 5

1
К сожалению, я пропустил знак равенства. Спасибо.
Aderstedt

Вы говорите, что собираетесь инициализировать categoriesPerPage, который является 2-димным массивом с vInt?
Дан

@Dan your'e право, пример просто продемонстрировать setпример, из-конечно , вы не можете назначить intв[int]
Daniel Кр

Сделал это миллион раз и все еще пропустил лишний знак = :)
Александр G

вам не нужна точка с запятой
Питер Шорн

51

Для всех, кто сталкивается с этим, убедитесь, что вы не пытаетесь изменить класс, а не экземпляр! (если вы не объявили переменную как статическую)

например.

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

instanceOfMyClass.variable = 'Foo' // Right!

5
В этом разница между staticпеременной и instanceпеременной, MyClass.variableона действительна, если вы объявите ее как статическую переменную (общую для всех экземпляров)
Даниэль Кром

Это была моя проблема. Я нахожу странным, когда XCode решает поставить класс первым в параметрах автозаполнения перед экземпляром с аналогичным именем, когда контекст, кажется, указывает на то, что я определенно использую экземпляр, а не сам класс. И в тех случаях, когда ваш экземпляр отличается только от случая к случаю, может быть трудно заметить, что вы выбрали класс, а не тот экземпляр, который вы хотели. Спасибо!
LeftOnTheMoon

19

Это говорит о том, что у вас есть переменная экземпляра (переменная видна / доступна только тогда, когда у вас есть экземпляр этого класса), и вы пытаетесь использовать ее в контексте статической области (метод класса).

Вы можете сделать переменную вашего экземпляра переменной класса, добавив статический атрибут / атрибут класса.

Вы создаете экземпляр своего класса и вызываете метод экземпляра для этой переменной.


В моем случае я попытался использовать переменную экземпляра в блоке завершения, вызываемом после инициализации экземпляра другого класса. Конечно, init - это функция класса, и объявление переменной экземпляра как статической решило проблему.
Рейнхард Меннер

8

Другой пример, у вас есть класс, как:

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

вы также получите такой же тип ошибки, как:

instance member x cannot be used on type x. 

Это потому, что вы присваиваете свой метод с ключевым словом «class» (что делает ваш метод методом типа) и используете like:

Album.getCurrentlyPlayingSongLyric(duration: 5)

но кто устанавливал переменную playingSong раньше? Хорошо. Вы не должны использовать ключевое слово класса для этого случая:

 // ...

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

 // ...

Теперь вы можете идти.


8

Иногда Xcode при переопределении методов добавляет class funcвместо просто func. Тогда в статическом методе вы не можете видеть свойства экземпляра. Это очень легко не заметить. Это был мой случай.

введите описание изображения здесь


Ах, спасибо! Потратил много времени на выяснение, почему я не получил ни одного из предложений автозаполнения члена экземпляра в Xcode. Это похоже на ошибку, я напишу радар с Apple A
Апурв Хатреджа

3

Ваша начальная проблема была:

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

Элемент экземпляра categoryPerPage нельзя использовать для типа ReportView

предыдущие сообщения правильно указывают, если вы хотите вычисляемое свойство , =знак ошибочный.

Дополнительная возможность для ошибки:

Если вы намеревались «Задать значение свойства по умолчанию с помощью замыкания или функции» , вам нужно лишь немного его изменить. (Примечание: этот пример явно не предназначен для этого)

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

Вместо удаления =добавляем() обозначение закрытия инициализации по умолчанию. (Это может быть полезно при инициализации кода пользовательского интерфейса, чтобы хранить все это в одном месте.)

Тем не менее, точно такая же ошибка возникает:

Элемент экземпляра categoryPerPage нельзя использовать для типа ReportView

Проблема заключается в попытке инициализировать одно свойство значением другого. Одним из решений является создание инициализатора lazy. Это не будет выполнено, пока значение не получено.

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

теперь компилятор доволен!


0

Я продолжал получать ту же ошибку, несмотря на создание переменной static. Решение: очистить сборку, очистить производные данные, перезапустить Xcode. Или сочетание клавиш Cmd + Shift + Alt + K

UserNotificationCenterWrapper.delegate = self

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

0

На тот случай, если кому-то действительно нужно подобное закрытие , это можно сделать следующим образом:

var categoriesPerPage = [[Int]]()
var numPagesClosure: ()->Int {
    return {
        return self.categoriesPerPage.count
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.