Ana içeriğe geç
  1. 100 Günde SwiftUI Notları/

11.Gün - Swift Struct - 2 : Access Control ve Static Property & Method

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ızca deposit() ve withdraw() methodlarının değiştirebileceği anlamına gelirdi.

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.

  1. Static koddan, non-static koda erişilemez. static property ve methodlar, non-static property ve methodlara atıfta bulunamaz.
  2. 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çin Self de kullanabiliriz.

İPUCU 💡: self ve Self farklı anlama geliyor;

  • self struct’ın mevcut değerini
  • Self ise mevcut türünü ifade ediyor.

self ve Self 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 nedenle Self ’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.

Bu yazı, SwiftUI Day 11 adresinde bulunan yazılardan kendim için aldığım notları içermektedir. Orjinal dersi takip etmek için lütfen bağlantıya tıklayın.