Swift - Erişim Kontrolü

Kod bloklarına erişimi kısıtlamak için modüller ve soyutlama erişim kontrolü ile yapılır. Sınıflara, yapılara ve numaralandırmalara özelliklerine, yöntemlerine, başlatıcılarına ve aboneliklerine göre erişim kontrol mekanizmaları ile erişilebilir. Bir protokoldeki sabitler, değişkenler ve işlevler sınırlandırılmıştır ve erişim kontrolü aracılığıyla genel ve yerel erişime izin verilir. Özelliklere, türlere ve işlevlere uygulanan erişim kontrolü 'varlıklar' olarak adlandırılabilir.

Erişim kontrol modeli, modüllere ve kaynak dosyalara dayanmaktadır.

Modül, tek bir kod dağıtım birimi olarak tanımlanır ve 'içe aktarma' anahtar sözcüğü kullanılarak içe aktarılabilir. Bir kaynak dosya, birden çok türe ve işleve erişmek için bir modülde bulunan tek bir kaynak kod dosyası olarak tanımlanır.

Swift 4 dili tarafından üç farklı erişim seviyesi sağlanmaktadır. Bunlar Genel, Dahili ve Özel erişimdir.

S.No Erişim Düzeyleri ve Tanım
1

Public

Varlıkların, tanımlayıcı modülü içe aktaran başka bir modülden bir kaynak dosya olan kendi tanımlama modüllerinden herhangi bir kaynak dosyada işlenmesini sağlar.

2

Internal

Varlıkların kendi tanımlama modüllerinden herhangi bir kaynak dosyada kullanılmasını sağlar, ancak bu modülün dışındaki herhangi bir kaynak dosyada kullanılamaz.

3

Private

Bir varlığın kullanımını kendi tanımlayıcı kaynak dosyasıyla sınırlar. Özel erişim, belirli bir kod işlevinin uygulama ayrıntılarını gizlemede rol oynar.

Sözdizimi

public class SomePublicClass {}
internal class SomeInternalClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

İşlev türleri için Erişim Kontrolü

Bazı işlevler, işlev içinde herhangi bir dönüş değeri olmadan bildirilmiş bağımsız değişkenlere sahip olabilir. Aşağıdaki program a ve b'yi sum () işlevinin argümanları olarak bildirir. Fonksiyonun içinde, a ve b argümanlarının değerleri, fonksiyon çağrısı sum () çağrılarak geçirilir ve değerleri yazdırılır, böylece dönüş değerleri ortadan kaldırılır. İşlevin dönüş türünü özel yapmak için, işlevin genel erişim düzeyini özel değiştiriciyle bildirin.

private func sum(a: Int, b: Int) {
   let a = a + b
   let b = a - b
   print(a, b)
}

sum(a: 20, b: 10)
sum(a: 40, b: 10)
sum(a: 24, b: 6)

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

30 20
50 40
30 24

Numaralandırma türleri için Erişim Denetimi

public enum Student {
   case Name(String)
   case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift 4")
var studMarks = Student.Mark(98,97,95)

switch studMarks {
   case .Name(let studName):
      print("Student name is: \(studName).")
   case .Mark(let Mark1, let Mark2, let Mark3):
      print("Student Marks are: \(Mark1),\(Mark2),\(Mark3).")
   
}

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

Student Marks are: 98,97,95

Swift 4 dilinde numaralandırma, bir numaralandırmanın bireysel durumları için otomatik olarak aynı erişim düzeyini alır. Örneğin, öğrencilerin adı ve üç konuda güvence altına alınan işaretlere erişmeyi düşünün, numaralandırma adı öğrenci olarak bildirilir ve enum sınıfında bulunan üyeler, dize veri türüne ait adlardır, işaretler veri türü Tamsayı'nın mark1, mark2 ve mark3 olarak temsil edilir. Öğrenci adına veya puanladıkları notlara erişmek için. Şimdi, anahtar durumu, bu vaka bloğu yürütülürse öğrenci adını yazdıracak, aksi takdirde öğrenci tarafından güvence altına alınan işaretleri yazdıracaktır. Her iki koşul da başarısız olursa, varsayılan blok yürütülür.

Alt Sınıflar için Erişim Kontrolü

Swift 4, kullanıcının mevcut erişim bağlamında erişilebilen herhangi bir sınıfı alt sınıflamasına izin verir. Bir alt sınıfın, üst sınıfından daha yüksek bir erişim düzeyi olamaz. Kullanıcının dahili bir üst sınıfın genel bir alt sınıfını yazması kısıtlanmıştır.

public class cricket {
   internal func printIt() {
      print("Welcome to Swift 4 Super Class")
   }
}

internal class tennis: cricket {
   override internal func printIt() {
      print("Welcome to Swift 4 Sub Class")
   }
}

let cricinstance = cricket()
cricinstance.printIt()

let tennisinstance = tennis()
tennisinstance.printIt()

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

Welcome to Swift Super Class
Welcome to Swift Sub Class

Sabitler, değişkenler, özellikler ve alt simgeler için Erişim Kontrolü

Swift 4 sabiti, değişkeni veya özelliği, türünden daha genel olarak tanımlanamaz. Özel tipte bir kamu mülkü yazmak geçerli değildir. Benzer şekilde, bir alt simge, dizininden veya dönüş türünden daha genel olamaz.

Bir sabit, değişken, özellik veya alt simge özel bir tür kullandığında, sabit, değişken, özellik veya alt simge de özel olarak işaretlenmelidir -

private var privateInstance = SomePrivateClass()

Getters ve Setters

Sabitler, değişkenler, özellikler ve abonelikler için oluşturucular ve ayarlayıcılar, ait oldukları sabit, değişken, özellik veya alt simge ile aynı erişim düzeyini otomatik olarak alır.

class Samplepgm {
   var counter: Int = 0{
      willSet(newTotal) {
         print("Total Counter is: \(newTotal)")
      }
      didSet {
         if counter > oldValue {
            print("Newly Added Counter \(counter - oldValue)")
         }
      }
   }
}

let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700

Başlatıcılar ve Varsayılan Başlatıcılar için Erişim Kontrolü

Özel başlatıcılara, başlattıkları türden daha düşük veya buna eşit bir erişim düzeyi atanabilir. Gerekli bir başlatıcı, ait olduğu sınıfla aynı erişim düzeyine sahip olmalıdır. Bir başlatıcının parametrelerinin türleri, başlatıcının kendi erişim düzeyinden daha özel olamaz.

Başlatma 'gerekli' anahtar sözcüğünün her bir alt sınıfını bildirmek için init () işlevinden önce tanımlanması gerekir.

class classA {
   required init() {
      let a = 10
      print(a)
   }
}
class classB: classA {
   required init() {
      let b = 30
      print(b)
   }
}
let res = classA()
let print = classB()

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

10
30
10

Varsayılan bir başlatıcı, bu tür genel olarak tanımlanmadıkça, başlattığı türle aynı erişim düzeyine sahiptir. Varsayılan başlatma genel olarak tanımlandığında dahili olarak kabul edilir. Kullanıcının başka bir modülde argümansız başlatıcı ile başlatılabilir olması için genel bir türe ihtiyacı olduğunda, tür tanımının bir parçası olarak açıkça bir genel argümansız başlatıcı sağlayın.

Protokoller için Erişim Kontrolü

Var olan bir protokolden işlevsellikleri devralmak için yeni bir protokol tanımladığımızda, her ikisinin de birbirinin özelliklerini devralması için aynı erişim seviyelerinde beyan edilmesi gerekir. Swift 4 erişim kontrolü, kullanıcıların 'dahili' bir protokolden miras alan 'genel' bir protokol tanımlamasına izin vermez.

public protocol tcpprotocol {
   init(no1: Int)
}
public class mainClass {
   var no1: Int      // local storage
   init(no1: Int) {
      self.no1 = no1 // initialization
   }
}
class subClass: mainClass, tcpprotocol {
   var no2: Int
   init(no1: Int, no2 : Int) {
      self.no2 = no2
      super.init(no1:no1)
   }
   
   // Requires only one parameter for convenient method
   required override convenience init(no1: Int) {
      self.init(no1:no1, no2:0)
   }
}

let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

res is: 20
res is: 30
res is: 50

Uzantılar için Erişim Kontrolü

Swift 4, kullanıcı bu uzantıyı protokol uygunluğu eklemek için kullandığında, kullanıcıların bir uzantı için açık bir erişim seviyesi değiştiricisi sağlamasına izin vermez. Uzantı içindeki her protokol gereksinimi uygulaması için varsayılan erişim düzeyi, kendi protokol erişim düzeyiyle sağlanır.

Jenerikler için Erişim Kontrolü

Jenerikler, kullanıcının tip parametrelerindeki tip kısıtlamalarına erişmek için minimum erişim seviyelerini belirlemesine izin verir.

public struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)
let deletetos = tos.pop()

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

Tür Takma Adları için Erişim Denetimi

Kullanıcı, farklı erişim denetimi türlerini ele almak için tür takma adları tanımlayabilir. Aynı erişim seviyesi veya farklı erişim seviyeleri kullanıcı tarafından tanımlanabilir. Tür takma adı 'özel' olduğunda, ilişkili üyeleri 'özel, genel türden dahili' olarak ilan edilebilir. Tür takma adı genel olduğunda, üyeler 'dahili' veya 'özel' ad olarak takma ad olamaz

Tanımladığınız tüm tür diğer adları, erişim kontrolü amacıyla farklı türler olarak değerlendirilir. Bir tür takma adı, takma adını verdiği türün erişim düzeyinden daha düşük veya ona eşit bir erişim düzeyine sahip olabilir. Örneğin, özel tür bir diğer ad, özel, dahili veya genel bir türe takma ad verebilir, ancak genel tür bir diğer ad, dahili veya özel bir türe diğer ad veremez.

public protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
   // original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
   
   // conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
func allItemsMatch<
   C1: Container, C2: Container
   where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
   (someContainer: C1, anotherContainer: C2) -> Bool {
   
   // check that both containers contain the same number of items
   if someContainer.count != anotherContainer.count {
      return false
   }
   
   // check each pair of items to see if they are equivalent
   for i in 0..<someContainer.count {
      if someContainer[i] != anotherContainer[i] {
         return false
      }
   }
   // all items match, so return true
   return true
}
var tos = Stack<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Where Clause")
print(tos.items)

var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)

Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]

Hızlı Kodlama ve Kod Çözme

Swift 4 yeni bir Codable Herhangi bir özel kod yazmadan ve değer türlerinizi kaybetme konusunda endişelenmenize gerek kalmadan, özel veri türlerini serileştirmenize ve serileştirmenize olanak tanıyan protokol.

struct Language: Codable {
   var name: String
   var version: Int
}
let swift = Language(name: "Swift", version: 4)
let java = Language(name: "java", version: 8)
let R = Language(name: "R", version: 3

Langauage'ın Kodlanabilir Protokol ile uyumlu olduğuna dikkat edin. Şimdi bunu tek bir basit satır kullanarak Json Veri Temsilcisine dönüştüreceğiz.

let encoder = JSONEncoder()
if let encoded = try? encoder.encode(java) {
   //Perform some operations on this value.
}

Swift, veri türünüzdeki tüm değerleri otomatik olarak kodlayacaktır.

Kod çözücü işlevini kullanarak verilerin kodunu çözebilirsiniz.

let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Language.self, from: encoded) {
   //Perform some operations on this value.
}

Hem JSONEncoder hem de onun özellik listesi muadili PropertyListEncoder, nasıl çalıştıklarını özelleştirmek için birçok seçeneğe sahiptir.