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

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

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

Ошибка компиляции с сообщением:

Элементы члена экземпляраPerPage не могут использоваться по типу 'ReportView'

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

Ответ 1

У вас просто есть синтаксическая ошибка при произнесении = {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;

Ответ 2

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

например.

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

instanceOfMyClass.variable = 'Foo' // Right!

Ответ 3

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

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

Вы можете сделать метод класса методом экземпляра, удалив атрибут класса.

Ответ 4

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

@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" (что делает ваш метод методом типа) и используя:

Album.getCurrentlyPlayingSongLyric(duration: 5)

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

 // ...

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

 // ...

Теперь вы свободны.

Ответ 5

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

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 }()
}

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

Ответ 6

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

UserNotificationCenterWrapper.delegate = self

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

Ответ 7

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

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