Com esta classe simples, estou recebendo o aviso do compilador
Tentativa de modificar / acessar
x
dentro de seu próprio setter / getter
e quando eu uso assim:
var p: point = Point()
p.x = 12
Eu recebo um EXC_BAD_ACCESS. Como posso fazer isso sem ivars de apoio explícitos?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
set
você deseja usardidSet
. As propriedades se comportam de maneira diferente no Swift que no Objective-C ou em outros idiomas quando você implementaset
. Veja a resposta abaixo de @jack e um exemplo dedidSet
partir @cSquirrelRespostas:
Setters e Getters se aplicam a
computed properties
; essas propriedades não têm armazenamento na instância - o valor do getter deve ser calculado a partir de outras propriedades da instância. No seu caso, não háx
como atribuir.Explicitamente: "Como posso fazer isso sem ivars de apoio explícitos". Você não pode - precisará de algo para fazer backup da propriedade computada. Tente o seguinte:
Especificamente, no Swift REPL:
fonte
Setters / getters no Swift são bem diferentes do ObjC. A propriedade se torna uma propriedade calculada, o que significa que não possui uma variável de suporte, como
_x
teria no ObjC.No código da solução abaixo, você pode ver
xTimesTwo
que não armazena nada, mas simplesmente calcula o resultado dex
.Consulte Documentos oficiais sobre propriedades computadas .
A funcionalidade que você deseja também pode ser Observadores de propriedades .
O que você precisa é:
Você pode modificar outras propriedades dentro do setter / getters, para que servem.
fonte
didSet
que permitirá alterar o valor imediatamente após ser definido. Nada para obter ...x
de volta paraoldValue
nodidSet
. Essa mudança de comportamento é muito confusa, proveniente das propriedades do Objective-C, obrigado!Você pode personalizar o valor configurado usando o observador de propriedades. Para fazer isso, use 'didSet' em vez de 'set'.
Quanto a getter ...
fonte
x
com um valor padrão nesse padrão?var x: Int = 0 { didSet { ...
.Para elaborar a resposta do GoZoner:
Seu problema real aqui é que você está chamando recursivamente o seu parceiro.
Como o comentário do código sugere acima, você está chamando infinitamente o getter da propriedade x, que continuará sendo executado até obter um código EXC_BAD_ACCESS (você pode ver o botão giratório no canto inferior direito do ambiente de playground do seu Xcode).
Considere o exemplo da documentação do Swift :
Observe como a propriedade computada ao centro nunca se modifica ou retorna na declaração da variável.
fonte
get
. Porque isso desencadearia outroget
que desencadearia outro. . . Nem imprima. Porque a impressão também exige 'obter' o valor antes que ela possa ser impressa!Para substituir
setter
egetter
para variáveis rápidas, use o código abaixoPrecisamos manter o valor da variável em uma variável temporária, pois tentar acessar a mesma variável cujo getter / setter está sendo substituído resultará em loops infinitos.
Podemos invocar o setter simplesmente assim
O Getter será chamado ao disparar abaixo da linha de código fornecida
fonte
Você está definindo recursivamente
x
comx
. Como se alguém lhe perguntasse quantos anos você tem? E você responde: "Tenho o dobro da minha idade". O que não tem sentido.Você deve dizer que tenho o dobro da idade de John ou qualquer outra variável que não seja você.
variáveis computadas são sempre dependentes de outra variável.
A regra do polegar é não acessar a propriedade em si a partir de dentro do getter ie
get
. Porque isso desencadearia outroget
que desencadearia outro. . . Nem imprima. Porque a impressão também exige 'obter' o valor antes que ela possa ser impressa!Como isso daria o seguinte aviso:
O erro parece vago assim:
Como alternativa, você pode querer usar
didSet
. ComdidSet
você manterá o valor que foi definido antes e acabou de ser definido. Para mais, veja esta resposta .fonte
Atualização: Swift 4
Na classe abaixo, setter e getter são aplicados à variável
sideLength
Criando objeto
Getter
Normatizador
fonte
Tente usar isto:
Essa é basicamente a resposta de Jack Wu, mas a diferença é que, na resposta de Jack Wu, sua variável x é
var x: Int
, na minha, minha variável x é assim:var x: Int!
então tudo o que fiz foi torná-la um tipo opcional.fonte
Atualização para o Swift 5.1
A partir do Swift 5.1, agora você pode obter sua variável sem usar a palavra-chave get . Por exemplo:
fonte
Setters e getters no Swift se aplicam a propriedades / variáveis calculadas. Na verdade, essas propriedades / variáveis não são armazenadas na memória, mas computadas com base no valor das propriedades / variáveis armazenadas.
Consulte a documentação Swift da Apple sobre o assunto: Swift Variable Declarations .
fonte
Aqui está uma resposta teórica. Isso pode ser encontrado aqui
fonte