Dengan kode berikut saya mencoba untuk mendefinisikan kelas model sederhana dan penginisialisasi gagal itu, yang mengambil kamus (json-) sebagai parameter. Penginisialisasi harus kembali nil
jika nama pengguna tidak ditentukan dalam json asli.
1. Mengapa kode tidak dapat dikompilasi? Pesan kesalahan mengatakan:
Semua properti yang disimpan dari instance kelas harus diinisialisasi sebelum mengembalikan nol dari penginisialisasi.
Itu tidak masuk akal. Mengapa saya harus menginisialisasi properti tersebut ketika saya berencana untuk mengembalikannya nil
?
2. Apakah pendekatan saya benar atau adakah ide atau pola umum lain untuk mencapai tujuan saya?
class User: NSObject {
let userName: String
let isSuperUser: Bool = false
let someDetails: [String]?
init?(dictionary: NSDictionary) {
if let value: String = dictionary["user_name"] as? String {
userName = value
}
else {
return nil
}
if let value: Bool = dictionary["super_user"] as? Bool {
isSuperUser = value
}
someDetails = dictionary["some_details"] as? Array
super.init()
}
}
swift
object-initializers
Kai Huppmann
sumber
sumber
canSetCalculableProperties
parameter boolean yang memungkinkan inisialisasi saya menghitung properti yang dapat atau tidak dapat dibuat dengan cepat. Misalnya, jika adadateCreated
kunci yang hilang dan saya dapat menyetel properti dengan cepat karenacanSetCalculableProperties
parameternya benar, maka saya cukup menyetelnya ke tanggal saat ini.Jawaban:
Pembaruan: Dari Swift 2.2 Change Log (dirilis 21 Maret 2016):
Untuk Swift 2.1 dan sebelumnya:
Menurut dokumentasi Apple (dan kesalahan kompiler Anda), kelas harus menginisialisasi semua properti yang disimpannya sebelum kembali
nil
dari penginisialisasi yang gagal:Catatan: Ini sebenarnya berfungsi dengan baik untuk struktur dan enumerasi, hanya saja tidak untuk kelas.
Cara yang disarankan untuk menangani properti tersimpan yang tidak dapat diinisialisasi sebelum penginisialisasi gagal adalah dengan mendeklarasikannya sebagai opsional yang tidak terbungkus secara implisit.
Contoh dari dokumen:
Dalam kasus Anda, bagaimanapun, hanya dengan mendefinisikan
userName
sebagaiString!
tidak memperbaiki kesalahan kompilasi karena Anda masih perlu khawatir tentang menginisialisasi properti pada kelas dasar AndaNSObject
,. Untungnya, denganuserName
didefinisikan sebagaiString!
, Anda sebenarnya dapat memanggilsuper.init()
sebelum Andareturn nil
yang akan menginisialisasiNSObject
kelas dasar Anda dan memperbaiki kesalahan kompilasi.sumber
Product
kelas) tidak dapat memicu kegagalan inisialisasi sebelum menetapkan nilai tertentu, meskipun dokumen mengatakan dapat. Dokumen tidak sinkron dengan versi Swift terbaru. Disarankan untuk membuatnyavar
untuk saat ini sajalet
. sumber: Chris Lattner .Menurut Chris Lattner ini adalah bug. Inilah yang dia katakan:
Sumber
EDIT:
Jadi swift sekarang open source dan menurut changelog ini diperbaiki sekarang dalam snapshot swift 2.2
sumber
Saya menerima bahwa jawaban Mike S adalah rekomendasi Apple, tetapi menurut saya itu bukan praktik terbaik. Inti dari sistem tipe yang kuat adalah memindahkan kesalahan runtime ke waktu kompilasi. "Solusi" ini mengalahkan tujuan itu. IMHO, lebih baik melanjutkan dan menginisialisasi nama pengguna
""
dan kemudian memeriksanya setelah super.init (). Jika userNames kosong diperbolehkan, maka setel bendera.sumber
Cara lain untuk menghindari batasan ini adalah bekerja dengan fungsi-kelas untuk melakukan inisialisasi. Anda bahkan mungkin ingin memindahkan fungsi itu ke ekstensi:
Menggunakannya akan menjadi:
sumber
Meskipun Swift 2.2 telah dirilis dan Anda tidak lagi harus menginisialisasi objek sepenuhnya sebelum gagal dalam penginisialisasi, Anda perlu menahan kudanya hingga https://bugs.swift.org/browse/SR-704 diperbaiki.
sumber
Saya menemukan kaleng ini dilakukan di Swift 1.2
Ada beberapa syarat:
Contoh:
sumber
Kutipan Dari: Apple Inc. “ Bahasa Pemrograman Cepat. IBooks. https://itun.es/sg/jEUH0.l
sumber
Anda dapat menggunakan kemudahan init :
sumber