හෙලෝ! මගේ නම කිරිල් ෆමින්, මම iOS සංවර්ධකයෙක්.
අද, මට Swift හි initializers වැනි සරල මාතෘකාවක් හොඳින් පරීක්ෂා කිරීමට අවශ්යයි. එහි සරල බව පෙනෙන්නට තිබුණත්, සමහර විට මෙම මාතෘකාව පිළිබඳ සම්පූර්ණ අවබෝධයක් නොමැතිකම නිසා විස්තර සොයා බැලීමකින් තොරව ඉක්මනින් නිවැරදි කිරීමට අවශ්ය කලකිරීමට පත්වන දෝෂ ඇති වේ.
මෙම ලිපියෙන්, අපි ආරම්භකයින්ට අදාළ සියල්ල ආවරණය කරන්නෙමු, ඒවා අතර:
අභිරුචි එකක් නිර්වචනය කරන අතරතුර ව්යුහයේ සාමාජික මට්ටමේ ආරම්භකය රඳවා ගන්නේ කෙසේද
පන්තිවල සෑම විටම ආරම්භකයක් ලිවීම අවශ්ය නොවන්නේ ඇයි
නම් කරන ලද ආරම්භක යන්ත්රයක super.init
ඇමතීම සැමවිටම අවශ්ය නොවන්නේ ඇයි?
super.init
ඇමතීමට පෙර උපපංතියක සියලුම ක්ෂේත්ර පුරවා තිබිය යුත්තේ ඇයි?
උපපංතිවල අවම අතිච්ඡාදනයන් සහිත සියලුම මාපිය ආරම්භකකරුවන්ට ප්රවේශ වන්නේ කෙසේද
හරියටම required
ආරම්භකයක් අවශ්ය වූ විට
UIView.init()
සැමවිටම පරාමිතීන් නොමැතිව හඳුන්වනු ලබන්නේ ඇයි, නමුත් init(frame:)
සහ init(coder:)
අභිබවා යන්නේ ඇයි?
...සහ තවත්. නමුත් අපි එය පියවරෙන් පියවර ගනිමු.
var
vs let
required
ආරම්භකකාරකය: generics, protocols, Self()
, final
UIView()
ඇපල් හි මාර්ගෝපදේශය වන ස්විෆ්ට් ක්රමලේඛන භාෂාව (6) (ආරම්භකයින් සඳහා පුදුම සහගත ලෙස සවිස්තරාත්මක) මෙසේ පවසයි:
ආරම්භ කිරීම යනු පන්තියක, ව්යුහයක හෝ ගණන් කිරීමේ අවස්ථාවක් භාවිතය සඳහා සකස් කිරීමේ ක්රියාවලියයි. මෙම ක්රියාවලියට එම අවස්ථාවේ ගබඩා කර ඇති සෑම දේපලක් සඳහාම ආරම්භක අගයක් සැකසීම සහ නව අවස්ථාව භාවිතයට සූදානම් වීමට පෙර අවශ්ය වෙනත් ඕනෑම සැකසුමක් හෝ ආරම්භයක් සිදු කිරීම ඇතුළත් වේ.
ඔබ මෙම ආරම්භක ක්රියාවලිය ක්රියාත්මක කරන්නේ initializers නිර්වචනය කිරීමෙනි, ඒවා විශේෂිත වර්ගයක නව අවස්ථාවක් නිර්මාණය කිරීමට කැඳවිය හැකි විශේෂ ක්රම වැනිය. Objective-C initializers මෙන් නොව, Swift initializers අගයක් ආපසු ලබා නොදේ. ඔවුන්ගේ ප්රධාන කාර්යභාරය වන්නේ පළමු වරට භාවිතා කිරීමට පෙර වර්ගයක නව අවස්ථා නිවැරදිව ආරම්භ කර ඇති බව සහතික කිරීමයි.
හොඳයි, මම හිතන්නේ මට මෙතනට කිසිවක් එකතු කිරීමට අවශ්ය නැහැ.
ව්යුහ ආරම්භකකරුවන් සාකච්ඡා කිරීමෙන් පටන් ගනිමු. උරුමයක් නොමැති නිසා මෙය තරමක් සරල ය, නමුත් ඔබ දැනගත යුතු නීති කිහිපයක් තවමත් තිබේ.
අපි සරල ව්යුහයක් ලියමු:
struct BankAccount { let amount: Double let isBlocked: Bool } let bankAccount = BankAccount(amount: 735, isBlocked: Bool)
ආරම්භකයක් පැහැදිලිව ප්රකාශ නොකර ව්යුහය ආරම්භ කිරීමට අපට හැකි වූ බව සලකන්න. මෙය සිදුවන්නේ ව්යුහයන්ට සම්පාදකය මඟින් ජනනය කරන ලද සාමාජික මට්ටමේ ආරම්භකයක් ලැබෙන බැවිනි. මෙය ක්රියාත්මක වන්නේ ව්යුහයන් සඳහා පමණි .
Refactor → Generate memberwise initializer තේරීමෙන්, එය පෙනෙන්නේ කෙසේදැයි ඔබට දැක ගත හැකිය:
init(amount: Double, isBlocked: Bool) { self.amount = amount self.isBlocked = isBlocked }
අත්සනින්, සියලු පරාමිතීන් සඳහා අගයන් ලබා දීමට අපොහොසත් වීමෙන් සම්පාදන දෝෂයක් ඇති වන බව පහසුවෙන් දැකගත හැකිය:
let bankAccount = BankAccount(amount: 735) // ❌ Missing argument for parameter 'isBlocked' in call
කෙසේ වෙතත්, ඔබට අවශ්ය තර්ක ගණන අඩු කිරීමට අවශ්ය නම්, ඔබට අභිරුචි ආරම්භකයක් අර්ථ දැක්විය හැකිය:
init(amount: Double, isBlocked: Bool = false) { self.amount = amount isBlocked = isBlocked } let bankAccount = BankAccount(amount: 735) // ✅
isBlocked
පුරවා නොමැති නම්, සියලුම ව්යුහ ගුණාංග ආරම්භකකාරකයක පුරවා ගත යුතු බැවින්, මෙය සම්පාදන දෝෂයකට හේතු වන බව සලකන්න.
var
vs let
ක්ෂේත්රයක් පැහැදිලිව පුරවා ගැනීමට අවශ්ය නොවන එකම අවස්ථාව වන්නේ එය විකල්ප ( ?
) විචල්යයක් වන විට පමණි ( var
). එවැනි අවස්ථාවන්හිදී, ක්ෂේත්රය පෙරනිමියෙන් nil
වනු ඇත:
struct BankAccount { let amount: Double var isBlocked: Bool? init(amount: Double) { self.amount = amount } } let bankAccount = BankAccount(amount: 735) // ✅
කෙසේ වෙතත්, මෙම අවස්ථාවේදී අපි memberwise initializer භාවිතා කිරීමට උත්සාහ කළහොත්, අපට සම්පාදන දෝෂයක් ලැබෙනු ඇත:
let bankAccount = BankAccount( amount: 735, isBlocked: false ) // ❌ Extra argument 'isBlocked' in call
මෙය සිදුවන්නේ අභිරුචි ආරම්භකයක් ප්රකාශ කිරීමෙන් සාමාජික මට්ටමේ ආරම්භකය ඉවත් වන බැවිනි. එය තවමත් පැහැදිලිව අර්ථ දැක්විය හැකි නමුත් එය ස්වයංක්රීයව ලබා ගත නොහැක.
කෙසේ වෙතත්, memberwise initializer රඳවා ගැනීමට කුඩා උපක්රමයක් තිබේ: අභිරුචි initializer extension
ප්රකාශ කරන්න.
struct BankAccount { let amount: Double var isBlocked: Bool? } extension BankAccount { init(amount: Double) { self.amount = amount } } let barclaysBankAccount = BankAccount(amount: 735) // ✅ let revolutBankAccount = BankAccount(amount: 812, isBlocked: false) // ✅ print(barclaysBankAccount.isBlocked) // nil print(barclaysBankAccount.isBlocked) // false
ව්යුහයන් සඳහා සාරාංශය
var
ක්ෂේත්ර පෙරනිමියෙන් nil
සකසා ඇතextension
පන්තියක් සඳහා ප්රාථමික ආරම්භකය නම් කරන ලද ආරම්භකය වේ. එය අරමුණු දෙකක් ඉටු කරයි:
class Animal { var name: String init(name: String) { self.name = name } } class Dog: Animal { var breed: String var name: String init(breed: String, name: String) { self.breed = breed super.init(name: name) } }
super.init
ඇමතීමට පෙර සියලුම ක්ෂේත්ර පිරවිය යුතුය . මන්ද, superclass initializer උපපංතිය මගින් අභිබවා ගිය ක්රම කැඳවිය හැකි අතර එමඟින් ජනාකීර්ණ නොවූ උපපංති ගුණාංග වෙත ප්රවේශ විය හැකිය.
class Animal { var age: Int init(age: Int) { self.age = age getInfo() } func getInfo() { print("Age: ", age) } } class Dog: Animal { var breed: String init(breed: String, age: Int) { self.breed = breed // imagine we haven't done this super.init(age: age) } override func getInfo() { print("Age: ", age, ", breed: ", breed) } }
මේ අනුව, අපි self.breed = breed
සකසා නොතිබුනේ නම්, අපට ධාවන කාල දෝෂයක් ඇති වීමට ඉඩ තිබුණි, මන්ද Animal
initializer එක Dog
පන්තියෙන් overrided getInfo()
ක්රමය කැඳවනු ඇත. මෙම ක්රමය තවමත් ජනනය කර නොමැති breed
දේපල වෙත ප්රවේශ වීමට උත්සාහ කරයි.
ව්යුහයන් මෙන් නොව, පන්තිවලට ව්යංග සාමාජික මට්ටමේ ආරම්භකයක් නොලැබේ. ආරම්භ නොකළ ගුණාංග තිබේ නම්, සම්පාදන දෝෂයක් ඇතිවේ:
class Animal { // ❌ Class 'Animal' has no initializers var age: Int }
class Animal { // ✅ var age: Int = 0 }
class Animal { // ✅ var age: Int? }
class Animal { } // ✅
පන්තිවලට පහසු ආරම්භකයක් ද තිබිය හැකිය. නම් කරන ලද ආරම්භකයන් මෙන් නොව, ඒවා මුල සිටම වස්තුවක් නිර්මාණය නොකරන නමුත් අනෙකුත් ආරම්භකයන්ගේ තර්කනය නැවත භාවිතා කිරීමෙන් ආරම්භක ක්රියාවලිය සරල කරයි.
class Rectangle { var width: Double var height: Double init(width: Double, height: Double) { self.width = width self.height = height } convenience init(side: Double) { self.init(width: side, height: side) // uses a designated initializer of self } }
Convenience initializers හට designated initializers හෝ වෙනත් convenience initializers ඇමතිය හැක. අවසාන වශයෙන්, designated initializer සැමවිටම කැඳවනු ලැබේ.
පහසු ආරම්භක යන්ත්ර සෑම විටම තිරස් අතට යයි (self.init), සහ නම් කරන ලද ආරම්භක යන්ත්ර සිරස් අතට යයි (super.init).
උපපංතියක් නව ගුණාංග ප්රකාශ කළ වහාම, සුපිරිපංතියේ සියලුම පහසු ආරම්භක වෙත ප්රවේශය අහිමි වේ.
class Animal { var age: Int var name: String init(age: Int, name: String) { self.age = age self.name = name } convenience init(age: Int) { self.init(age: age, name: "Default") } convenience init(name: String) { self.init(age: 0, name: name) } } class Dog: Animal { var breed: String init(age: Int, name: String, breed: String) { self.breed = breed super.init(age: age, name: name) } } let dog = Dog(age: 3) // ❌ Missing arguments for parameters 'breed', 'name' in call
සුපිරි පන්තියේ නම් කරන ලද සියලුම ආරම්භක අභිබවා යාමෙන් මෙය නිවැරදි කළ හැක.
class Dog: Animal { // ... override init(age: Int, name: String) { self.breed = "Mixed" super.init(age: age, name: name) } } let dog = Dog(age: 3) // ✅
මේ ආකාරයෙන්, ඊළඟ උපපංතියේ පහසු ආරම්භකයක් භාවිතා කිරීමට, ඔබ ආරම්භක දෙකක් අභිබවා යා යුතු බව දැකීම පහසුය.
class GuideDog: Dog { var isTrained: Bool override init(age: Int, name: String) { self.isTrained = false super.init(age: age, name: name) } override init(age: Int, name: String, breed: String) { self.isTrained = false super.init(age: age, name: name, breed: breed) } init(age: Int, name: String, breed: String, isTrained: Bool) { self.isTrained = isTrained super.init(age: age, name: name, breed: breed) } } let dog = GuideDog(age: 3) // ✅
කෙසේ වෙතත්, පහසුව සඳහා අතික්රමණය කිරීමේ ආරම්භකයක් භාවිතා කිරීමෙන් මෙය වළක්වා ගත හැකිය.
class Dog: Animal { var breed: String convenience override init(age: Int, name: String) { self.init(age: age, name: name, breed: "Mixed") // self, not super } init(age: Int, name: String, breed: String) { self.breed = breed super.init(age: age, name: name) } } class GuideDog: Dog { var isTrained: Bool // override init(age: Int, name: String) { // self.isTrained = false // // super.init(age: age, name: name, breed: "Mixed") // } convenience override init(age: Int, name: String, breed: String) { self.init(age: age, name: name, breed: breed, isTrained: false) // self, not super } init(age: Int, name: String, breed: String, isTrained: Bool) { self.isTrained = isTrained super.init(age: age, name: name, breed: breed) } } let dog = GuideDog(age: 3) // ✅
දැන් අපට සෑම උපපංතියකම පැහැදිලිව නිශ්චිත ආරම්භක 2 ක් පමණක් ඇත.
convenience override initializers super.init
වෙනුවට self
designated init ලෙස හඳුන්වන ආකාරය සැලකිල්ලට ගන්න.
මෙම උපක්රමය Tjeerd විසින් රචිත "Swift in Depth" හි 5 වන පරිච්ඡේදයේ හොඳින් පැහැදිලි කර ඇත, එය මම බෙහෙවින් නිර්දේශ කරන පොතකි.
super.init()
ලෙස හඳුන්වයි.උපපංතියක් නව පරාමිතීන් හඳුන්වා නොදෙන්නේ නම්, එය සුපිරිපංතියේ සියලුම ආරම්භක ස්වයංක්රීයව උරුම කර ගන්නා බව අපි දැනටමත් සාකච්ඡා කර ඇත්තෙමු.
class Base { let value: Int init() { value = 0 } init(value: Int) { self.value = value } } class Subclass: Base { } let subclass = Subclass() // ✅ let subclass = Subclass(value: 3) // ✅
කෙසේ වෙතත්, තවත් වැදගත් කරුණක් තිබේ: සුපිරි පන්තියට නම් කරන ලද එක් ආරම්භකයක් පමණක් තිබේ නම් සහ එය පරාමිති රහිත නම් ( init()
තර්ක නොමැතිව), එවිට උප පන්තියේ පැහැදිලිව ප්රකාශ කරන ලද ආරම්භකයින්ට super.init()
ඇමතීමට අවශ්ය නොවේ . මෙම අවස්ථාවේදී, Swift සම්පාදකය ස්වයංක්රීයව ඇමතුම ලබා ගත හැකි super.init()
තර්ක නොමැතිව ඇතුල් කරයි.
class Base { init() { } } class Subclass: Base { let secondValue: Int init(secondValue: Int) { self.secondValue = secondValue // ✅ without explicit super.init() } }
කේතය සම්පාදනය වන්නේ super.init()
ව්යංගයෙන් හැඳින්වෙන බැවිනි. පහත උදාහරණ කිහිපයක් සඳහා මෙය ඉතා වැදගත් වේ.
උපපංතියකට මූලික පන්තියට සමාන ආරම්භකකාරකයක් තිබිය යුතු සෑම අවස්ථාවකම required
ආරම්භකකාරකයක් භාවිතා වේ. එය super.init()
ලෙසද හැඳින්විය යුතුය. required
ආරම්භකකාරකයක් අවශ්ය වන අවස්ථා සඳහා උදාහරණ පහත දැක්වේ.
සාමාන්ය වර්ගයකින් init
ඇමතීමට හැකි වන්නේ එය required init
ලෙස ප්රකාශ කිරීමෙන් පමණි.
class Base { } class Subclass: Base { } struct Factory<T: Base> { func initInstance() -> T { // ❌ Constructing an object of class T() // type 'T' with a metatype value } // must use a 'required' initializer }
මෙම කේතය සම්පාදනය නොවේ, මන්ද Factory
Base
හි උප පන්ති ගැන කිසිවක් නොදන්නා බැවිනි. මෙම විශේෂිත අවස්ථාවේදී, Subclass
පරාමිතීන් නොමැතිව init()
එකක් තිබුණද, එය නව ක්ෂේත්රයක් හඳුන්වා දුන්නේ නම් සිතන්න:
class Subclass: Base { let value: Int init(value: Int) { self.value = value } }
මෙන්න, එහි තවදුරටත් හිස් init
නොමැති බැවින්, එය required
පරිදි ප්රකාශ කළ යුතුය.
class Base { required init() { } } class Subclass: Base { } struct Factory<T: Base> { static func initInstance() -> T { // ✅ T() } } let subclass = Factory<Subclass>.initInstance()
අපි Subclass
required init
පැහැදිලිව ප්රකාශ නොකළද, සම්පාදකයා එය අප වෙනුවෙන් ජනනය කළ බව සලකන්න. මෙය සම්පාදක සහාය තුළ සාකච්ඡා කරන ලදී. required init
ස්වයංක්රීයව උරුම වූ අතර එය super.init()
ලෙස හැඳින්වේ.
class Subclass: Base { required init() { super.init() } }
ප්රොටෝකෝලවල ප්රකාශ කර ඇති සියලුම ආරම්භක required
විය යුතුය:
protocol Initable { init() } class InitableObject: Initable { init() { // ❌ Initializer requirement 'init()' can only // be satisfied by a 'required' initializer } // in non-final class 'InitableObject' }
නැවතත්, මෙය අවශ්ය වන්නේ සම්පාදකයා විසින් උපපංතිය ප්රොටෝකෝල ආරම්භකය ක්රියාත්මක කරන බව සහතික කිරීම සඳහා ය. අප දැනටමත් දන්නා පරිදි, මෙය සැමවිටම සිදු නොවේ - init
required
නොවේ නම්, උපපංතිය එය අභිබවා යාමට බැඳී නොමැති අතර තමන්ගේම ආරම්භකය නිර්වචනය කළ හැකිය.
class IntValue: InitableObject { let value: Int init(value: Int) { self.value = value } } let InitableType: Initable.Type = IntValue.self let initable: Initable = InitableType.init()
ඇත්ත වශයෙන්ම, Base.init()
required
නොවන නිසා පහත කේතය සම්පාදනය නොවේ.
class InitableObject: Initable { required init() { } // ✅ } class IntValue: InitableObject { let value: Int required init() { self.value = 0 } init(value: Int) { self.value = value } }
ස්ථිතික ක්රම වලදී Self()
ආරම්භකය ඇමතීමේදීද මෙවැනිම තත්වයක් ඇතිවේ.
class Base { let value: Int init(value: Int) { self.value = value } static func instantiate() -> Self { Self(value: 3) // ❌ Constructing an object of class type 'Self' } // with a metatype value must use a 'required' initializer }
සෑම විටම මෙන්, ගැටළුව පවතින්නේ උරුමය තුළ ය:
class Subclass: BaseClass { let anotherValue: Int init(anotherValue: Int) { self.anotherValue = anotherValue } } let subclass = Subclass.instantiate() // ❌
class BaseClass { let value: Int required init(value: Int) { // ✅ self.value = value } static func instantiate() -> Self { Self(value: 3) } }
required
ඉවත් කිරීම: final
required
හි අරමුණ උපපංතිවල ආරම්භකයක් ක්රියාත්මක කිරීම බලාත්මක කිරීම බැවින්, ස්වාභාවිකවම, final
මූල පදය භාවිතා කරමින් උරුමය තහනම් කිරීමෙන් ආරම්භකයක් required
ලෙස සලකුණු කිරීමේ අවශ්යතාවය ඉවත් වේ.
protocol Initable { init() } final class InitableObject: Initable { } // ✅
protocol ValueInitable { init(value: Int) } final class ValueInitableObject: ValueInitable { init(value: Int) { } // ✅ }
init()
පමණක් තිබේ නම්, එය උප පන්තියේ ආරම්භක යන්ත්රවල ස්වයංක්රීයව හැඳින්වේ.Self()
වල භාවිතය සඳහා උපපංතිවල එහි පැවැත්ම සහතික කිරීම සඳහා required
ආරම්භකයක් අවශ්ය වේ. පරාමිතීන් නොමැතිව UIView()
ආරම්භකය පිළිබඳ කෙටි සඳහනක්, එය ලේඛනවල සොයාගත නොහැකි නමුත් අභිරහස් ලෙස සෑම තැනකම භාවිතා වේ.
හේතුව UIView
හට පරාමිතීන් නොමැතිව init()
එකක් ඇති NSObject
වෙතින් උරුම වීමයි. එබැවින් , මෙම ආරම්භකකාරකය UIView
අතුරුමුහුණතෙහි පැහැදිලිව ප්රකාශ කර නැත, නමුත් එය තවමත් පවතී:
@available(iOS 2.0, *) @MainActor open class UIView : UIResponder, NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem, UIFocusItemContainer, CALayerDelegate { open class var layerClass: AnyClass { get } public init(frame: CGRect) public init?(coder: NSCoder) open var isUserInteractionEnabled: Bool // no init()
කෙසේ වෙතත්, ආවරණය යටතේ, මෙම ආරම්භකකාරකය කේතයෙන් ආරම්භ කළ විට init(frame:)
ලෙසද, අතුරුමුහුණත් සාදන්නා හරහා ආරම්භ කළ විට init(coder:)
ලෙසද හඳුන්වයි. මෙය සිදුවන්නේ UIView
තමන්ගේම NSObject.init()
ක්රියාත්මක කිරීම සපයන බැවිනි, method_getImplementation
NSObject.init()
සහ UIView.init()
සඳහා විවිධ ලිපින ආපසු ලබා දෙන බව තහවුරු කළ හැකිය.
අසාර්ථක විය හැකි init එකක් යනු විකල්පයක් ආපසු ලබා දෙන එකක් පමණි
final class Failable { let positiveValue: Int init?(value: Int) { guard value > 0 else { return nil } positiveValue = value } }
අමු අගයක් සහිත එනම් වලට නොමිලේ init?(rawValue:)
enum Direction: String { case north case west case south case east } let north = Direction(rawValue: "north")
ඔබට enums සඳහා අභිරුචි init එකක් ද නිර්මාණය කළ හැකිය. සියලුම enum inits self
පැවරිය යුතුය.
enum DeviceType { case phone case tablet init(screenWidth: Int) { self = screenWidth > 800 ? .tablet : .phone } }
අපි Swift හි initializers වල සියලුම අත්යවශ්ය අංග ආවරණය කර ඇත්තෙමු:
ආරම්භකයක, සියලුම ක්ෂේත්ර පුරවා තිබිය යුතුය.
විකල්ප var
ගුණාංග පෙරනිමියෙන් nil
.
ව්යුහයන්ට නොමිලේ සාමාජිකත්ව ආරම්භකයක් ලැබේ.
අභිරුචි ආරම්භකයක් අර්ථ දක්වා ඇති විට සාමාජික මට්ටමේ ආරම්භකය අතුරුදහන් වේ .
නම් කරන ලද ආරම්භකයක් සියලුම ක්ෂේත්ර පුරවා ඇති බව සහතික කරන අතර super.init()
අමතයි.
පහසු ආරම්භකයක් නම් කරන ලද ආරම්භකයක් ඇමතීමෙන් ආරම්භ කිරීම සරල කරයි.
පහසු ආරම්භක යන්ත්ර සෑම විටම තිරස් අතට යයි ( self.init
), සහ නම් කරන ලද ආරම්භක යන්ත්ර සිරස් අතට යයි ( super.init
).
උපපංති නව ගුණාංග ප්රකාශ කළහොත් පහසුව සඳහා ආරම්භකයක් ලබා ගත නොහැක.
සුපිරි පන්තියක පහසුව සඳහා ආරම්භක යන්ත්රය ප්රතිසාධනය කිරීම සඳහා, එහි නම් කරන ලද සියලුම ආරම්භක යන්ත්ර අභිබවා යා යුතුය.
අතිච්ඡාදනය කිරීම් ගණන අවම කිරීම සඳහා, පහසුව සඳහා අතිච්ඡාදනය කිරීමේ ආරම්භකයක් භාවිතා කළ හැකිය.
උපපංතියක් නව පරාමිතීන් හඳුන්වා නොදෙන්නේ නම්, එය ස්වයංක්රීයව එහි සුපිරිපංතියෙන් සියලුම ආරම්භකයන් උරුම කර ගනී.
සුපිරි පන්තියේ පරාමිතීන් නොමැතිව init()
පමණක් තිබේ නම්, එය ස්වයංක්රීයව උප පන්තියේ ආරම්භක තුළ කැඳවනු ලැබේ.
අවශ්ය ආරම්භකයක්, ජෙනරික්ස්, ප්රොටෝකෝල සහ Self()
වල භාවිතය සඳහා උපපංතිවල එහි පැවැත්ම සහතික කරයි.
UIView.init()
මඟින් UIView.init(frame:)
හෝ UIView.init(coder:)
අමතයි.
අසාර්ථක ආරම්භකයක් විකල්පයක් ආපසු ලබා දෙයි.
අමු අගයක් සහිත එනම් වලට නොමිලේ init?(rawValue:)
ලැබේ.
සියලුම enum ආරම්භකයින් self
පැවරිය යුතුය.
මෙම ලිපියෙන් ඔබට ප්රයෝජනවත් යමක් හමු වූ බව මම බලාපොරොත්තු වෙමි. යමක් අපැහැදිලි නම් හෝ ඔබට සාවද්ය බවක් පෙනේ නම්, නොමිලේ පැහැදිලි කිරීමක් සඳහා ටෙලිග්රෑම් හරහා මාව සම්බන්ධ කර ගැනීමට නිදහස් වන්න: @kfamyn .