Sadece harici okuma, dahili özelliği okuma yazma


103

Swift'de, bir özelliğin yalnızca harici olarak okunacağı, ancak ona sahip olan sınıf (ve alt sınıflar) tarafından dahili olarak değiştirilebilir olduğu ortak modeli tanımlamanın geleneksel yolu nedir?

Objective-C'de aşağıdaki seçenekler vardır:

  • Özelliği arabirimde salt okunur olarak bildirin ve özelliğe dahili olarak erişmek için bir sınıf uzantısı kullanın. Bu mesaj tabanlı erişimdir, dolayısıyla KVO, atomiklik vb. İle iyi çalışır.
  • Özelliği arabirimde salt okunur olarak bildirin, ancak destek ivarına dahili olarak erişin. Bir ivar için varsayılan erişim korumalı olduğundan, bu, alt sınıfların da değeri değiştirebildiği, ancak alanın aksi takdirde salt okunur olduğu bir sınıf hiyerarşisinde iyi çalışır.

Java'da kural şöyledir:

  • Korunan bir alanı bildirin ve herkese açık, salt okunur bir alıcı (yöntem) uygulayın.

Swift'in deyimi nedir?

Yanıtlar:


219

Bir sınıf özelliği verildiğinde, özellik bildiriminin önüne erişim değiştiricinin önüne parantez koyarak getveya setarasına ekleyerek farklı bir erişim düzeyi belirtebilirsiniz . Örneğin, genel alıcı ve özel ayarlayıcıya sahip bir sınıf özelliği şu şekilde ilan edilecektir:

private(set) public var readonlyProperty: Int

Önerilen okuma: Getters ve Setters

Martin'in erişilebilirlik seviyesi ile ilgili düşünceleri hala geçerlidir - yani protecteddeğiştirici yoktur , internalsadece modüle erişimi kısıtlar, sadece privatemevcut dosyaya ve publichiçbir kısıtlama olmaksızın.

Swift 3 notları

2 yeni erişim düzenleyiciler, fileprivateve opensüre, dil eklendi privateve publicbiraz değiştirilmiş edilmiş:

  • openyalnızca sınıf ve sınıf üyeleri için geçerlidir: bir sınıfın alt sınıflara alınmasına veya bir üyenin, tanımlandıkları modülün dışında geçersiz kılınmasına izin vermek için kullanılır. publicbunun yerine sınıfı veya üyeyi herkese açık hale getirir, ancak miras alınamaz veya geçersiz kılınamaz

  • privateartık bir üyeyi yalnızca çevreleyen bildirimden görünür ve erişilebilir kılar, oysa fileprivatebulunduğu dosyanın tamamı için

Daha fazla ayrıntı burada .


Güzel! (Eksik varanahtar kelimeyi derlemek için ekleme özgürlüğünü aldım .)
Martin R

oh çok teşekkürler :) Genelde oyun alanından kopyalayıp yapıştırırım ama bu sefer muhtemelen yanlış yaptım.
Antonio

10
Ocak-2015 itibariyle, bu sözdiziminin, dış sınıf değilse public- olması gerektiği internalya da hiç olmaması gerektiği (varsayılan olarak - publicya da internal) - yaniprivate(set) var readonlyProperty: Int
Grimxn

1
Sözdizimi, koddan hemen önce bir genel alıcı ve özel ayarlayıcı ile bir sınıf özelliği yazdığım dikkate alındığında doğrudur - bu sadece bir örnek. Ancak evet, özellikler için erişim değiştiricileri, sınıf / yapı erişim değiştiricisi ile "uyumlu" olmalıdır.
Antonio

Son paragrafla ilgili olarak, cevabın yazılmasından bu yana değiştiğini tahmin ediyorum, ancak privateşimdi mevcut beyannameyle (dosya değil) fileprivatesınırlı ve mevcut dosyayla sınırlandırılabilir. Ayrıca publicbazı kısıtlamaları vardır ve openhiçbir kısıtlama için gerekli değildir. Detaylar burada .
Nigel

2

@Antonio'ya göre, readOnlymülk değeri olarak halka açık ve readWriteözel olarak erişmek için tek bir mülk kullanabiliriz . Aşağıda benim resmim:

class MyClass {

    private(set) public var publicReadOnly: Int = 10

    //as below, we can modify the value within same class which is private access
    func increment() {
        publicReadOnly += 1
    }

    func decrement() {
        publicReadOnly -= 1
    }
}

let object = MyClass()
print("Initial  valule: \(object.publicReadOnly)")

//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1

object.increment()
print("After increment method call: \(object.publicReadOnly)")

object.decrement()
print("After decrement method call: \(object.publicReadOnly)")

Ve işte çıktı:

  Initial  valule: 10
  After increment method call: 11
  After decrement method call: 10
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.