- Görkem Güray/
- 100 Günde SwiftUI Notları/
- 11.Gün - Swift Struct - 2 : Access Control ve Static Property & Method/
11.Gün - Swift Struct - 2 : Access Control ve Static Property & Method
Table of Contents
Swift Access Control #
Varsayılan olarak, Swift Struct’ların property ve method’larına erişiminde herhangi bir sınırlama yoktur. Fakat genellikle bu durum pek istediğimiz bir şey değildir. Bazı property ve method’lara dışarıdan erişimi kısıtlamak isteyebiliriz. Bu problemi anlayabilmek için örneğimize bakalım;
struct BankAccount {
var funds = 0
mutating func deposit(amount: Int) {
funds += amount
}
mutating func withdraw(amount: Int) -> Bool {
if funds >= amount {
funds -= amount
return true
} else {
return false
}
}
}
Yukarıdaki Struct’ın para yatırma ve para çekmeyi temsil eden deposit
ve withdraw
method’ları bulunmaktadır. İşlemler şu şekilde yapılabilir.
var account = BankAccount()
account.deposit(amount: 100)
let success = account.withdraw(amount: 200)
if success {
print("Withdrew money successfully")
} else {
print("Failed to get the money")
}
Fakat funds
property herhangi bir kontrol olmadan doğrudan erişilip değiştirilebilmektedir. Fakat biz funds
’a doğrudan erişmek istemiyoruz. Erişim işleminin sadece deposit
ve withdraw
methodları ile yapılmasını istiyoruz.
account.funds -= 1000
Yukarıdaki gibi bir kod yazmak, bizim programda kurduğumuz mantığı tamamen devredışı bırakmaktadır.
Bu sorunun üstesinden gelmek için, funds
’a sadece ait olduğu struct içinden erişilebilir olmasını söyleyebiliriz.
private var funds = 0
Artık struct dışından funds
’a erişmek mümkün değil. Fakat deposit
ve withdraw
property’ye erişebilmektedir.
Bu access control olarak isimlendirilmektedir. Access control bir struct’ın property ve methodlarına struct dışından nasıl erişileceğini kontrol etmektedir.
Swift’in bize sunduğu birkaç seçenek;
private
: “Struct’ın dışında hiçbir şeyin bunu kullanmasına izin verme” dediğimizde.fileprivate
: “Geçerli dosya dışında hiçbir şeyin bunu kullanmasına izin verme” dediğimizde.public
: “Herkes, heryerde bunu kullansın” dediğimizde.private(set)
: “Bu property’i herkesin okumasına izin ver, ancak yalnızca benim methodlarımın yazmasına izin ver.” anlamına gelmektedir.- Bunu
BankAcount
için kullansaydık,account.funds
’u struct dışında yazdırabileceğimiz, ancak değeri yalnızcadeposit()
vewithdraw()
methodlarının değiştirebileceği anlamına gelirdi.
- Bunu
Not : Bir veya daha fazla property için private
access control kullanıyorsak, büyük ihtimalle kendi initializer’ımızı yazmamız gerekmektedir.
Access Control ‘e Neden İhtiyaç Duyarız? #
Access Control kodumuzun farklı bölümlerine erişimi kısıtlıyor. Tamam ama peki neden?
Bazen access control sahip olmadığımız bir kodda kullanılır, bu sebeple access control’ü kaldıramayız. Örneğin Apple’ın API’lerinde bu durumu görebiliriz. Apple API’leri kullanmamıza izin verirken, yapabileceklerimiz ve yapamayacaklarımız ile ilgili olarak kısıtlamalar koyar.
Kendi kodumuzda access control’ü elbette kaldırabiliriz. Ama bu mantıksız bir durum oluşturur. Access Control ile bir kural (veya kurallar) oluşturur, ardından Swift’e bu kurallara uymamız gerektiğini söyleriz.
Static Property ve Method #
Struct’a property ve mothod’lar ekleyebiliriz. Her Struct instance’ında bu property ve methodların bir kopyası bulunur. Böylelikle bir instance üzerinde çağırdığımız method başka bir instance’ın property’sini okumaz.
Bazen, bir property veya method’u struct’ın instance’ı yerine Struct’ın kendisine ekleyerek, doğrudan kullanmak isteyebiliriz. Bu teknik genelde örnek data oluşturmak ve sabit dataları depolamak için kullanışlı olabilir.
Static özelliklerini anlayabilmek için basit bir örneğe bakalım;
struct School {
static var studentCount = 0
static func add(student: String) {
print("\(student) joined the school.")
studentCount += 1
}
}
Burada static
keyword’ü bulunan studentCount
property’si ve add
methodu, School
struct’ının örneklerine değil, struct’ın kendisine aittir.
School.add(student: "Taylor Swift")
print(School.studentCount)
//ÇIKTI:
//----------------------------------------
//Taylor Swift joined the school.
//1
School
dan herhangi bir instance oluşturmadığımız halde add()
ve studentCount
’u doğrudan struct üzerinden kullanabildik. Çünkü bunların ikisi de static’tir, yani struct’ın instance’larında benzersiz olarak bulunmazlar.
Bu aynı zamanda studentCount
property’sini mutating
olarak işaretlenmemiş bir method ile değiştirebildiğimiz de açıklar. mutating
yalnızca sabit (constant) olarak oluşturulan struct instance’ları için gereklidir, add()
çağrılırken ise ortada bir instance yoktur.
Static ve non-static property ve methodları birbirleri ile kullanırken iki adet kural vardır.
- Static koddan, non-static koda erişilemez. static property ve methodlar, non-static property ve methodlara atıfta bulunamaz.
- Non-static koddan static koda erişmek için her zaman
School.studentCount
gibi türün (type) adı kullanılır. Geçerli türe başvurmak içinSelf
de kullanabiliriz.
İPUCU 💡:
self
veSelf
farklı anlama geliyor;
self
struct’ın mevcut değeriniSelf
ise mevcut türünü ifade ediyor.
self
veSelf
arasındaki farkı unutmak kolaydır. Fakat Swift’in genelinde kullanılan isimlendirmeye benzemektedir. Tüm veri türlerimizi büyük harfle başlatırız (Int
,Double
,Bool
vb.) bu nedenleSelf
’in de büyük harfle başlaması mantıklıdır.
Static Kullanım Örnekleri #
Örnek-1:
Bir uygulamadaki ortak verileri düzenli bir şekilde tutmak için static kullanılabilir.
struct AppData {
static let version = "1.3 beta 2"
static let saveFilename = "settings.json"
static let homeURL = "https://www.hackingwithswift.com"
}
Örneğin uygulamamın herhangi bir yerinde versiyon numarasına ihtiyacım varsa AppData.version
şeklinde bu bilgiye ulaşabilirim.
Örnek-2:
Struct’ların örneklerini oluşturmak için kullanılabilir. SwiftUI’da uygulamayı geliştirirken canlı önizlemeleri kullanabiliriz. Canlı önizlemeler ise örnek veri ile daha iyi sonuçlar vermektedir.
struct Employee {
let username: String
let password: String
static let example = Employee(username: "cfederighi", password: "hairforceone")
}
Employee
’den bir instance’a ihtiyacımız olduğunda, Employee.example
’ı kullanabiliriz.
100 Days of SwiftUI Checkpoint - 6 #
Bu yazıyı İngilizce olarak da okuyabilirsiniz.
You can also read this article in English.