Jawaban yang ada hanya menceritakan setengah dari conveniencecerita. Separuh cerita yang lain, separuh dari tidak ada jawaban yang ada, menjawab pertanyaan yang telah diposting Desmond dalam komentar:
Mengapa Swift memaksa saya untuk meletakkan conveniencedi depan inisialisasi saya hanya karena saya perlu menelepon self.initdari itu? `
Saya menyentuhnya sedikit dalam jawaban ini , di mana saya membahas beberapa aturan inisialisasi Swift secara detail, tetapi fokus utama ada pada requiredkata tersebut. Tetapi jawaban itu masih menyinggung sesuatu yang relevan dengan pertanyaan ini dan jawaban ini. Kita harus memahami cara kerja pewarisan initializer Swift.
Karena Swift tidak memungkinkan untuk variabel yang tidak diinisialisasi, Anda tidak dijamin akan mewarisi semua (atau apa pun) inisialisasi dari kelas yang Anda warisi. Jika kami subkelas dan menambahkan variabel instance yang tidak diinisialisasi ke dalam subkelas kami, kami telah berhenti mewarisi inisialisasi. Dan sampai kita menambahkan inisialisasi kita sendiri, kompiler akan meneriaki kita.
Agar lebih jelas, variabel instance yang tidak diinisialisasi adalah variabel instance apa saja yang tidak diberi nilai default (dengan mengingat bahwa opsional dan opsional yang tidak terbuka secara otomatis mengasumsikan nilai default nil).
Jadi dalam hal ini:
class Foo {
var a: Int
}
aadalah variabel instance tidak diinisialisasi. Ini tidak akan dikompilasi kecuali kami memberikan anilai default:
class Foo {
var a: Int = 0
}
atau inisialisasi adalam metode penginisialisasi:
class Foo {
var a: Int
init(a: Int) {
self.a = a
}
}
Sekarang, mari kita lihat apa yang terjadi jika kita subkelas Foo, ya?
class Bar: Foo {
var b: Int
init(a: Int, b: Int) {
self.b = b
super.init(a: a)
}
}
Baik? Kami menambahkan variabel, dan kami menambahkan penginisialisasi untuk menetapkan nilai bsehingga akan dikompilasi. Bergantung pada bahasa apa Anda berasal, Anda mungkin berharap bahwa inisialisasi Barbawaan Foo,, init(a: Int). Tapi ternyata tidak. Dan bagaimana mungkin? Bagaimana Foo's init(a: Int)know bagaimana menetapkan nilai ke bvariabel yang Barditambahkan? Tidak. Jadi kita tidak dapat menginisialisasi aBar instance dengan penginisialisasi yang tidak dapat menginisialisasi semua nilai kami.
Apa hubungannya semua ini dengan convenience ?
Baiklah, mari kita lihat aturan tentang pewarisan initializer :
Aturan 1
Jika subkelas Anda tidak menentukan inisialisasi yang ditunjuk, subisialisasi Anda secara otomatis akan mewarisi semua inisialisasi yang ditentukan oleh superclass.
Aturan 2
Jika subclass Anda memberikan implementasi dari semua inisialisasi yang ditentukan oleh superclass-baik dengan mewarisinya sesuai aturan 1, atau dengan memberikan implementasi kustom sebagai bagian dari definisi-maka secara otomatis mewarisi semua inisialisasi kenyamanan superclass.
Perhatikan Aturan 2, yang menyebutkan inisialisasi kenyamanan.
Jadi apa yang conveniencekata kunci yang lakukan yaitu menunjukkan kepada kita yang initializers dapat diwariskan oleh subclass bahwa variabel add misalnya tanpa nilai default.
Mari kita ambil contoh Basekelas ini:
class Base {
let a: Int
let b: Int
init(a: Int, b: Int) {
self.a = a
self.b = b
}
convenience init() {
self.init(a: 0, b: 0)
}
convenience init(a: Int) {
self.init(a: a, b: 0)
}
convenience init(b: Int) {
self.init(a: 0, b: b)
}
}
Perhatikan kita memiliki tiga convenience inisialisasi di sini. Itu berarti kami memiliki tiga inisialisasi yang dapat diwariskan. Dan kami memiliki satu penginisialisasi yang ditunjuk (penginisialisasi yang ditunjuk hanyalah penginisialisasi yang bukan penginisialisasi kenyamanan).
Kami dapat membuat instance instance dari kelas dasar dalam empat cara berbeda:

Jadi, mari kita membuat subkelas.
class NonInheritor: Base {
let c: Int
init(a: Int, b: Int, c: Int) {
self.c = c
super.init(a: a, b: b)
}
}
Kami mewarisi dari Base. Kami menambahkan variabel instan kami sendiri dan kami tidak memberikan nilai default, jadi kami harus menambahkan inisialisasi kami sendiri. Kami menambahkan satu, init(a: Int, b: Int, c: Int)tapi itu tidak cocok dengan tanda tangan dari Basekelas yang ditunjuk initializer: init(a: Int, b: Int). Itu berarti, kita tidak mewarisi apapun initializers dari Base:

Jadi, apa yang akan terjadi jika kami mewarisi dari Base, tetapi kami melanjutkan dan menerapkan penginisialisasi yang cocok dengan penginisialisasi yang ditunjuk dari Base?
class Inheritor: Base {
let c: Int
init(a: Int, b: Int, c: Int) {
self.c = c
super.init(a: a, b: b)
}
convenience override init(a: Int, b: Int) {
self.init(a: a, b: b, c: 0)
}
}
Sekarang, selain dua inisialisasi yang kami terapkan langsung di kelas ini, karena kami menerapkan inisialisasi Basekelas pencocokan yang ditunjuk oleh initializer, kami harus mewarisi semua inisialisasi Basekelas convenience:

Fakta bahwa penginisialisasi dengan tanda tangan yang cocok ditandai sebagai conveniencetidak membuat perbedaan di sini. Ini hanya berarti bahwa Inheritorhanya memiliki satu inisialisasi yang ditunjuk. Jadi jika kita mewarisi dari Inheritor, kita hanya perlu menerapkan satu penginisialisasi yang ditunjuk, dan kemudian kita akan mewarisi Inheritorpenginisialisasi kenyamanan, yang pada gilirannya berarti kita telah menerapkan semua Baseinisialisasi yang ditunjuk dan dapat mewarisi convenienceinisialisasi.