O membro da instância não pode ser usado no tipo

139

Eu tenho a seguinte classe:

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

A compilação falha com a mensagem:

O membro da instância 'categoriesPerPage' não pode ser usado no tipo 'ReportView'

O que isto significa?

Aderstedt
fonte
12
Supondo que você declarará uma propriedade computada em numPagesvez de um fechamento exclua o sinal de igual:var numPages: Int { return categoriesPerPage.count }
vadian
1
Pode ser explicado com mais detalhes exatamente o que essa mensagem de erro significa? Eu estou vendo isso em um contexto completamente diferente.
William Entriken
2
Quando você declara um bloco no escopo da classe, como acima, você fica limitado ao que está disponível no tipo Você não tem acesso a nenhum membro da instância.
Aderstedt
Nota: A mensagem de erro é semelhante à que você recebe ao tentar criar uma variável lenta, mas esqueceu um dos requisitos . No seu caso, você não deseja uma variável lenta, pois categoriesPerPageé definida como em varvez de let.
Senseful
1
Remove = a partir de: var numpages: Int =
andrewz

Respostas:

132

Você apenas tem erro de sintaxe ao dizer = {return self.someValue}. o= não é necessário.

Usar :

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

}

se você quiser obter apenas você pode escrever

var numPages: Int {
     return categoriesPerPage.count
}

com a primeira maneira, você também pode adicionar observadores como set willSet&didSet

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

permitindo usar = operatorcomo setter

myObject.numPages = 5
Daniel Krom
fonte
1
Opa, eu perdi o sinal de igual. Obrigado.
Aderstedt
Você está dizendo que vai inicializar categoriesPerPage, que é uma matriz de 2 dim com a vqual é Int?
Dan
@ Dan Your'e direita, O exemplo é apenas para demonstrar setexemplo, de curso não é possível atribuir intpara[int]
Daniel Krom
Feito isso um milhão de vezes e ainda perdeu o extra de sinal = :)
Alexandre G
você não precisa do ponto e vírgula fam
Peter Schorn
51

Para quem mais se deparar com isso, verifique se você não está tentando modificar a classe e não a instância! (a menos que você tenha declarado a variável como estática)

por exemplo.

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

instanceOfMyClass.variable = 'Foo' // Right!
Derek
fonte
5
Esta é a diferença entre a staticvariável e instancevariável, MyClass.variableé válido se você declará-lo como variável estática (compartilhado entre todas as instâncias)
Daniel Krom
Este foi o meu problema. Acho meio estranho quando o XCode decide colocar a classe em primeiro lugar nas opções de preenchimento automático antes de uma instância com nome semelhante, quando o contexto parece apontar para mim definitivamente usando a instância e não a própria classe. E nos casos em que sua instância difere apenas por caso, pode ser difícil perceber que você escolheu a classe e não a instância que pretendia. Obrigado!
LeftOnTheMoon
19

Está dizendo que você tem uma variável de instância (o var só é visível / acessível quando você tem uma instância dessa classe) e está tentando usá-la no contexto de um escopo estático (método de classe).

Você pode tornar sua variável de instância uma variável de classe adicionando o atributo static / class.

Você instancia uma instância de sua classe e chama o método de instância nessa variável.

Vlad
fonte
No meu caso, tentei usar uma variável de instância no bloco de conclusão chamado depois que uma instância de outra classe foi inicializada. Obviamente, um init é uma função de classe, e declarar a variável de instância como estática resolveu o problema.
Reinhard Männer
8

Outro exemplo é que você tem classe como:

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

você também receberá o mesmo tipo de erro como:

instance member x cannot be used on type x. 

É porque você atribui seu método com a palavra-chave "class" (que torna seu método um método de tipo) e usando o seguinte:

Album.getCurrentlyPlayingSongLyric(duration: 5)

mas quem definiu a variável playingSong antes? Está bem. Você não deve usar a palavra-chave da classe nesse caso:

 // ...

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

 // ...

Agora você está livre para ir.

mgyky
fonte
8

Às vezes, o Xcode quando substitui métodos adiciona, em class funcvez de apenas func. Então, no método estático, você não pode ver as propriedades da instância. É muito fácil ignorar isso. Esse foi o meu caso.

insira a descrição da imagem aqui

milczi
fonte
Ah obrigado! Passei muito tempo descobrindo por que não estava recebendo nenhuma das sugestões de preenchimento automático do membro da instância no Xcode. Isso parece um bug, vou arquivar um radar com a Apple Apo
Apoorv Khatreja
3

Seu problema inicial foi:

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

O membro da instância 'categoriesPerPage' não pode ser usado no tipo 'ReportView'

as postagens anteriores apontam corretamente, se você deseja uma propriedade computada , o =sinal está incorreto.

Possibilidade adicional de erro:

Se sua intenção era "Definir um valor de propriedade padrão com um fechamento ou uma função" , você também precisará alterá-lo levemente. (Nota: este exemplo obviamente não tinha a intenção de fazer isso)

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

Em vez de remover o =, adicionamos() para indicar um fechamento de inicialização padrão. (Isso pode ser útil ao inicializar o código da interface do usuário, para manter tudo em um só lugar.)

No entanto, ocorre exatamente o mesmo erro :

O membro da instância 'categoriesPerPage' não pode ser usado no tipo 'ReportView'

O problema está tentando inicializar uma propriedade com o valor de outra. Uma solução é fazer o inicializador lazy. Não será executado até que o valor seja acessado.

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

agora o compilador está feliz!

bshirley
fonte
0

Eu continuava recebendo o mesmo erro, apesar de fazer a variável static. Solução: Limpar Compilação, Limpar Dados Derivados, Reiniciar o Xcode. Ou atalho Cmd + Shift + Alt + K

UserNotificationCenterWrapper.delegate = self

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

Caso alguém realmente precise de um fechamento como esse, isso pode ser feito da seguinte maneira:

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