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


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.