Dengan kelas sederhana ini saya mendapatkan peringatan compiler
Mencoba untuk memodifikasi / mengakses
x
dalam setter / pengambil sendiri
dan ketika saya menggunakannya seperti ini:
var p: point = Point()
p.x = 12
Saya mendapatkan EXC_BAD_ACCESS. Bagaimana saya bisa melakukan ini tanpa dukungan vars secara eksplisit?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
set
Anda ingin gunakandidSet
. Properti berperilaku berbeda di Swift daripada Objective-C atau bahasa lain ketika Anda menerapkanset
. Lihat jawaban di bawah ini dari @jack dan contohdidSet
dari @cSquirrelJawaban:
Setter dan Getters berlaku untuk
computed properties
; properti seperti itu tidak memiliki penyimpanan dalam instance - nilai dari pengambil dimaksudkan untuk dihitung dari properti instance lainnya. Dalam kasus Anda, tidak ada yangx
ditugaskan.Secara eksplisit: "Bagaimana saya bisa melakukan ini tanpa dukungan ivar secara eksplisit". Anda tidak bisa - Anda akan membutuhkan sesuatu untuk membuat cadangan properti yang dihitung. Coba ini:
Secara khusus, dalam REPL Swift:
sumber
Setter / getter di Swift sangat berbeda dari ObjC. Properti menjadi properti yang dihitung yang artinya tidak memiliki variabel pendukung seperti yang
_x
akan terjadi pada ObjC.Dalam kode solusi di bawah ini Anda dapat melihat
xTimesTwo
tidak tidak menyimpan apa-apa, tetapi hanya menghitung hasil darix
.Lihat dokumen resmi tentang properti yang dihitung .
Fungsi yang Anda inginkan mungkin juga Pengamat Properti .
Yang Anda butuhkan adalah:
Anda dapat memodifikasi properti lain dalam setter / getter, yang memang dimaksudkan untuk itu.
sumber
didSet
yang akan memungkinkan Anda untuk mengubah nilai segera setelah ditetapkan. Tidak ada yang bisa didapat ...x
kembali keoldValue
dalamdidSet
. Perubahan perilaku ini sangat membingungkan karena berasal dari properti Objective-C, terima kasih!Anda dapat menyesuaikan nilai yang ditetapkan menggunakan pengamat properti. Untuk melakukan ini gunakan 'didSet' bukan 'set'.
Adapun pengambil ...
sumber
x
dengan nilai default dalam pola ini?var x: Int = 0 { didSet { ...
.Untuk menguraikan jawaban GoZoner:
Masalah sebenarnya Anda di sini adalah bahwa Anda secara rekursif memanggil pengambil Anda.
Seperti yang dikomentari oleh kode di atas, Anda memanggil pengambil properti x, yang akan terus dijalankan hingga Anda mendapatkan kode EXC_BAD_ACCESS (Anda dapat melihat pemintal di sudut kanan bawah lingkungan taman bermain Xcode Anda).
Pertimbangkan contoh dari dokumentasi Swift :
Perhatikan bagaimana pusat menghitung properti tidak pernah memodifikasi atau mengembalikan dirinya sendiri dalam deklarasi variabel.
sumber
get
. Karena itu akan memicu yang lainget
yang akan memicu yang lain. . . Jangan pernah mencetaknya. Karena pencetakan juga mengharuskan untuk mendapatkan nilai sebelum dapat mencetaknya!Untuk mengganti
setter
dangetter
untuk variabel cepat gunakan kode yang diberikan di bawah iniKita perlu menyimpan nilai variabel dalam variabel sementara, karena mencoba mengakses variabel yang sama yang pengambil / penyetelnya ditimpa akan menghasilkan loop tak terbatas.
Kita bisa meminta setter seperti ini
Getter akan dipanggil pada pembakaran di bawah baris kode yang diberikan
sumber
Anda rekursif mendefinisikan
x
denganx
. Seolah-olah seseorang bertanya berapa umurmu? Dan Anda menjawab "Saya dua kali usia saya". Itu tidak ada artinya.Anda harus mengatakan usia saya dua kali John atau variabel lain selain diri Anda sendiri.
variabel yang dihitung selalu tergantung pada variabel lain.
Aturan praktis adalah tidak pernah mengakses properti itu sendiri dari dalam pengambil yaitu
get
. Karena itu akan memicu yang lainget
yang akan memicu yang lain. . . Jangan pernah mencetaknya. Karena pencetakan juga mengharuskan untuk mendapatkan nilai sebelum dapat mencetaknya!Karena itu akan memberikan peringatan berikut:
Kesalahannya terlihat tidak jelas seperti ini:
Sebagai alternatif, Anda mungkin ingin menggunakan
didSet
. DengandidSet
Anda akan mendapatkan nilai yang ditetapkan sebelumnya dan baru saja ditetapkan untuk. Untuk lebih lanjut lihat jawaban ini .sumber
Pembaruan: Swift 4
Dalam setter dan pengambil kelas di bawah ini diterapkan untuk variabel
sideLength
Menciptakan objek
Getter
Setter
sumber
Coba gunakan ini:
Ini pada dasarnya adalah jawaban Jack Wu, tetapi perbedaannya adalah bahwa dalam jawaban Jack Wu variabel x-nya adalah
var x: Int
, pada variabel x saya, adalah seperti ini:,var x: Int!
jadi yang saya lakukan hanyalah menjadikannya tipe opsional.sumber
Pembaruan untuk Swift 5.1
Pada Swift 5.1 Anda sekarang bisa mendapatkan variabel Anda tanpa menggunakan kata kunci get . Sebagai contoh:
sumber
Setter dan getter di Swift berlaku untuk properti / variabel yang dihitung. Properti / variabel ini sebenarnya tidak disimpan dalam memori, melainkan dihitung berdasarkan nilai properti / variabel yang disimpan.
Lihat dokumentasi Swift Apple tentang masalah ini: Deklarasi Variabel Swift .
sumber
Ini jawaban teoretisnya. Itu bisa ditemukan di sini
sumber