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


138

У мене є такий клас:

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

Не вдалося компілювати повідомлення:

Учасника екземпляра "kategorijePerPage" не можна використовувати для типу "ReportView"

Що це означає?


12
Здогадуючись, що ви збираєтесь оголосити обчислену властивість, numPagesа не про закриття, видаліть знак рівності:var numPages: Int { return categoriesPerPage.count }
vadian

1
Чи можна пояснити, будь ласка, більш ретельно, що саме означає це повідомлення про помилку? Я бачу це в абсолютно іншому контексті.
Вільям Ентрікен

2
Коли ви оголошуєте блок в області класу, як вище, ви обмежуєтесь тим, що доступно в цьому типі. Ви не маєте доступу до членів інстанції.
Aderstedt

Примітка. Повідомлення про помилку аналогічне тому, яке ви отримуєте при спробі створити змінну змінну, але забуло одну з вимог . У вашому випадку ви не бажаєте ледачої змінної, оскільки 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
На жаль, я пропустив знак рівності. Дякую.
Аддерштедт

Ви говорите, що збираєтеся ініціалізувати categoriesPerPage, який є 2-тьмяним масивом, з vяким Int?
Dan

@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справедлива, якщо ви оголосите її статичною змінною (поділяється між усіма примірниками)
Daniel Krom

Це була моя проблема. Мені здається дивним, коли XCode вирішує поставити клас першим у параметрах автозаповнення перед аналогічно названим екземпляром, коли контекст, здається, вказує на мене напевно, використовуючи екземпляр, а не сам клас. І у випадках, коли ваш екземпляр відрізняється лише від випадку, може бути важко помітити, що ви вибрали клас, а не екземпляр, який ви мали на меті. Дякую!
LeftOnTheMoon

19

Це говорить про те, що у вас є змінна інстанція (var є видимою / доступною лише тоді, коли у вас є екземпляр цього класу), і ви намагаєтесь використовувати її в контексті статичної області застосування (метод класу).

Ви можете зробити свій примірник змінною класу змінною, додавши атрибут static / class.

Ви інстанціюєте екземпляр свого класу та викликаєте метод екземпляра на цій змінній.


У моєму випадку я намагався використовувати змінну екземпляра в блоці завершення, викликаному після ініціалізації інстанції іншого класу. Звичайно, 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" (що робить ваш метод методом типу) і використовуєте:

Album.getCurrentlyPlayingSongLyric(duration: 5)

але хто раніше встановлював змінну playSong? Гаразд. Не слід використовувати ключове слово для цього випадку:

 // ...

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

 // ...

Тепер ви можете їхати.


7

Іноді Xcode, коли метод заміщення додає class funcзамість просто func. Тоді в статичному методі ви не можете побачити властивості екземпляра. Помітити це дуже просто. Це був мій випадок.

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


Ах, дякую! Довго витрачався, з'ясовуючи, чому я не отримував жодного з учасників екземпляра пропозицій щодо автозаповнення в Xcode. Це здається помилкою, я подам радіолокатор на Apple Apo
Апоорв Хатреджа,

3

Вашою початковою проблемою було:

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

Учасника екземпляра "kategorijePerPage" не можна використовувати для типу "ReportView"

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

Додаткова можливість помилки:

Якщо вашим наміром було "Встановлення значення властивості за замовчуванням із закриттям або функцією" , вам потрібно лише трохи змінити його. (Примітка: цей приклад, очевидно, не мав цього робити)

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

Замість того, щоб видаляти значення =, ми додамо ()для позначення закриття ініціалізації за замовчуванням. (Це може бути корисно при ініціалізації коду інтерфейсу, щоб зберегти все в одному місці.)

Однак трапляється точно така ж помилка :

Учасника екземпляра "kategorijePerPage" не можна використовувати для типу "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.