Swift'in erişim değiştiricileri var mı?


273

Objective-C örneğinde veriler public, protectedveya olabilir private. Örneğin:

@interface Foo : NSObject
{
  @public
    int x;
  @protected:
    int y;
  @private:
    int z;
  }
-(int) apple;
-(int) pear;
-(int) banana;
@end

Swift referansında herhangi bir erişim değiştiricisinden bahsetmedim. Swift'teki verilerin görünürlüğünü sınırlamak mümkün mü?


Ben de değil. Apple, en azından altyazı ile ön eklenmiş python gibi, özeller için görgü kurallarını tanıtmalıdır.
Ciantic


Yanıtlar:


419

İtibariyle Swift 3.0.1 vardır 4 erişim seviyelerinin en düşük (en kısıtlayıcı) en yüksek (en az kısıtlayıcı) aşağıda tarif edilen,.


1. openvepublic

Varlığın, tanımlayıcı modülün (hedef) dışında kullanılmasını sağlayın. Bir çerçeveye genel arabirimi belirtirken genellikle kullanır openveya publicerişirsiniz.

Ancak, openerişim yalnızca sınıflar ve sınıf üyeleri için geçerlidir ve publicerişimden şu şekilde farklıdır :

  • public sınıflar ve sınıf üyeleri yalnızca tanımlayıcı modül (hedef) içinde alt sınıflara ayrılabilir ve geçersiz kılınabilir.
  • open sınıflar ve sınıf üyeleri tanımlayıcı modülün (hedef) içinde ve dışında alt sınıflara ayrılabilir ve geçersiz kılınabilir.

// First.framework – A.swift

open class A {}

// First.framework – B.swift

public class B: A {} // ok

// Second.framework – C.swift

import First

internal class C: A {} // ok

// Second.framework – D.swift

import First

internal class D: B {} // error: B cannot be subclassed

2. internal

Bir varlığın tanımlayıcı modül (hedef) içinde kullanılmasını sağlar. internalErişimi genellikle bir uygulamanın veya çerçevenin dahili yapısını tanımlarken kullanırsınız .

// First.framework – A.swift

internal struct A {}

// First.framework – B.swift

A() // ok

// Second.framework – C.swift

import First

A() // error: A is unavailable

3. fileprivate

Bir varlığın kullanımını tanımlayıcı kaynak dosyasıyla kısıtlar. Bu fileprivateayrıntılar bir dosya içinde kullanıldığında, genellikle belirli bir işlev parçasının uygulama ayrıntılarını gizlemek için erişim kullanırsınız .

// First.framework – A.swift

internal struct A {

    fileprivate static let x: Int

}

A.x // ok

// First.framework – B.swift

A.x // error: x is not available

4. private

Bir varlığın kullanımını ek beyanıyla sınırlar. Bu privateayrıntıları yalnızca tek bir bildirimde kullanıldığında, belirli bir işlev parçasının uygulama ayrıntılarını gizlemek için genellikle erişimi kullanırsınız .

// First.framework – A.swift

internal struct A {

    private static let x: Int

    internal static func doSomethingWithX() {
        x // ok
    }

}

A.x // error: x is unavailable

37
Birisi bana neden bu kadar önemli olmadığını açıklayabilir mi?
Zaky Alman

15
OOP'ta her zaman özel veya korunması gereken bazı yöntemler veya değişkenler vardır. Bu, SOLID tasarımının uygulanmasına izin verir , çünkü büyük yöntemler, her biri kendi sorumluluğuna sahip olan, geçersiz kılınabilecek bir dizi daha küçük olana bölünür, ancak genel kullanım için sadece "ana" yöntem mevcut olmalıdır.
akashivskyy

19
Ben şahsen alt çizgi / özel karakter lider "özel" yöntemleri ile gibi çözümleri sevmiyorum. Kendim için bu koda bir göz attığım tek kişi olacağı garanti edilse bile, kodun daha fazla kaydedilmesini / hatalara daha az eğilimli olmasını sağlar, çünkü derleyici sadece yapmamanız gereken şeyleri yapmanıza engel olur. Bu yüzden "erişim kontrol mekanizmalarını" olabildiğince hızlı çıkarmaları gerektiğini düşünüyorum, bu yüzden insanlar kötü alışkanlıklara alışmayacaklar.
Jonas Eschmann

10
Xcode 6 beta sürüm notları: "Erişim kontrolü (kamu / özel üyeler) bu tohumda etkin değil. (15747445)"
Martin Ullrich

9
@alcalde Genel arabirim fikri oldukça değerlidir. Bir sınıftaki tüm kodların, genel API'nin bir parçası olan fonksiyonların içinde bulunması gerektiğini düşünüyorsanız, bunun oldukça sınırlayıcı olduğunu düşünüyorum. Öte yandan, belirli bir ortak API'ya sahip olmak, uygulamanın tüketicileri bozmadan değiştirmesine (özel yöntemlerin kullanımı dahil) izin verir. Birisi bir iç sınıf yöntemi kullanmak için 'ihtiyaç' varsa onlar sınıf 'işlevselliğinin sınırlarını yanlış anlamak hissediyorum (veya bir buggy sınıfı kullanmaya çalışıyorum).
jinglesthula

26

Hızlı 4 / Hızlı 5

Sözü gereğince Swift Belgeleri - Access Control , Swift sahiptir 5 Erişim Kontrolleri :

  • açık ve herkese açık : modüllerinin varlıklarından ve tanımlayan modülü ithal eden herhangi bir modülün varlıklarından erişilebilir.

  • internal : yalnızca modüllerinin varlıklarından erişilebilir. Varsayılan erişim düzeyidir.

  • fileprivate ve private : yalnızca tanımladığınız sınırlı bir kapsam dahilinde erişilebilir.



Open ve public arasındaki fark nedir ?

open , Swift'in önceki sürümlerinde herkese açık olanlarla aynıdır, diğer modüllerden sınıfların bunları kullanmasına ve devralmasına izin verir, yani: diğer modüllerden alt sınıflara ayrılabilirler. Ayrıca, diğer modüllerden üyelerin bunları kullanmasına ve geçersiz kılmasına izin verir. Aynı mantık modülleri için de geçerlidir.

Kamu diğer modülünden sınıflar bunları kullanmak, ancak izin değil , yani onlara miras: bunlar olamaz diğer modüllerden alt sınıflanamayacağını. Ayrıca, diğer modüllerden üyelerin bunları kullanmasına izin verir, ancak onları geçersiz kılmazlar. Modülleri için aynı açık mantığa sahiptirler (sınıfların bunları kullanmasına ve devralmasına izin verirler; Üyelerin bunları kullanmasına ve geçersiz kılmasına izin verirler).


Fileprivate ve private arasındaki fark nedir ?

fileprivate dosyasına tüm dosyalarından erişilebilir.

private'a yalnızca tek bir bildiriminden ve bu bildirimin aynı dosyadaki uzantılarına erişilebilir ; Örneğin:

// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
    private var aPrivate: String?
    fileprivate var aFileprivate: String?

    func accessMySelf() {
        // this works fine
        self.aPrivate = ""
        self.aFileprivate = ""
    }
}

// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
    func accessA() {
        // create an instance of "A" class
        let aObject = A()

        // Error! this is NOT accessable...
        aObject.aPrivate = "I CANNOT set a value for it!"

        // this works fine
        aObject.aFileprivate = "I CAN set a value for it!"
    }
}



Swift 3 ve Swift 4 Erişim Kontrolü arasındaki farklar nelerdir?

SE-0169 teklifinde belirtildiği gibi, Swift 4'e tek iyileştirme eklenmiştir, özel erişim kontrol kapsamının aynı dosyadaki bu beyanın uzantılarından erişilebilir olacak şekilde genişletilmesi ; Örneğin:

struct MyStruct {
    private let myMessage = "Hello World"
}

extension MyStruct {
    func printMyMessage() {
        print(myMessage)
        // In Swift 3, you will get a compile time error:
        // error: 'myMessage' is inaccessible due to 'private' protection level

        // In Swift 4 it should works fine!
    }
}

Bu nedenle, tüm dosyadan erişilebilir olması için fileprivatemyMessage olarak bildirmeye gerek yoktur .


17

Swift ya da ObjC'de (ya da yakut ya da java ya da…) “özel yöntem” yapmaktan bahsedildiğinde, bu yöntemler gerçekten özel değildir . Etraflarında gerçek bir erişim kontrolü yoktur. Biraz içgözlem bile sunan herhangi bir dil, geliştiricilerin gerçekten istedikleri takdirde sınıfın dışından bu değerlere ulaşmasını sağlar.

Burada gerçekten bahsettiğimiz şey, sadece istediğimiz işlevselliği sunan ve "özel" olarak gördüğümüz geri kalanını "gizleyen" halka açık bir arayüz tanımlamanın bir yoludur .

Arabirimleri bildirmek için Swift mekanizmasıdır protocolve bu amaçla kullanılabilir.

protocol MyClass {
  var publicProperty:Int {get set}
  func publicMethod(foo:String)->String
}

class MyClassImplementation : MyClass {
  var publicProperty:Int = 5
  var privateProperty:Int = 8

  func publicMethod(foo:String)->String{
    return privateMethod(foo)
  }

  func privateMethod(foo:String)->String{
    return "Hello \(foo)"
  }
}

Unutmayın, protokoller birinci sınıf türlerdir ve bir türün olabileceği her yerde kullanılabilir. Ve bu şekilde kullanıldıklarında, sadece kendi arayüzlerini ortaya koyarlar, uygulama türünün arayüzlerini değil.

Bu nedenle, parametre türleriniz MyClassyerine kullandığınız sürece MyClassImplementation, hepsi işe yarayacaktır:

func breakingAndEntering(foo:MyClass)->String{
  return foo.privateMethod()
  //ERROR: 'MyClass' does not have a member named 'privateMethod'
}

Swift'i çıkarmak için güvenmek yerine türle açık olmanız gereken bazı doğrudan atama vakaları vardır, ancak bu bir anlaşma kırıcı gibi görünmemektedir:

var myClass:MyClass = MyClassImplementation()

Protokolleri bu şekilde kullanmak semantik, makul derecede özlüdür ve gözlerime ObjC'de bu amaçla kullandığımız Sınıf Uzantılarına çok benziyor.


1
Protokoller varsayılan bir argümana sahip olmamıza izin vermiyorsa, yine de protokole uygun isteğe bağlı parametrelerle ortak bir yöntem nasıl oluşturabilirim?
bdurao

Ne demek istediğini anlamıyorum. Aşağıda isteğe bağlı bir parametreyle genel bir yöntem oluşturulur. Bir sorun yok gibi görünüyor: gist.github.com/anonymous/17d8d2d25a78644046b6
jemmons

Herhangi bir nedenle isteğe bağlı parametre projemde olması gerektiği gibi çalışmıyor, GitHub örneğinize benzer bir şey zaten denemişti. Protokolde varsayılan bir parametre ayarlayamadığımız için takıldım ve bir soru sordum. Yardım etmeye çalıştığın için teşekkürler.
bdurao

Hepimiz bir şeyin hacklenebilir olduğunu biliyoruz. Erişim düzenleyicilere neden ihtiyacımız olan bazı siparişlere ihtiyacımız var
canbax

14

Anlayabildiğim kadarıyla, 'genel', 'özel' veya 'korumalı' anahtar kelimeler yok. Bu, her şeyin herkese açık olduğunu gösterir.

Ancak Apple , uygulama türünün ayrıntılarını gizlemek için insanların " protokolleri " (dünyanın geri kalanı tarafından arabirimler olarak adlandırılır) ve fabrika tasarım modelini kullanmasını bekliyor olabilir .

Bu genellikle yine de kullanmak için iyi bir tasarım modelidir; çünkü mantıksal yazım sistemini aynı tutarken uygulama sınıfı hiyerarşinizi değiştirmenize izin verir .


Bu, kuplajı azalttığı ve testi kolaylaştırabildiği için güzeldir.
Scroog1

4
Protokolün uygulama sınıfını gizlemenin bir yolu olsaydı daha iyi olurdu, ama öyle görünmüyor.
David Moles

Herkes bu modelin açıklayıcı bir örneğini verebilir mi?
bloudermilk

Bu cevap önceki Swift sürümlerinde geçerliydi, artık geçerli değil gibi görünüyor :) lütfen cevabımı kontrol et .
Ahmad F

12

Protokollerin, kapakların ve iç içe / iç sınıfların bir kombinasyonunu kullanarak, Swift'teki bilgileri şu anda gizlemek için modül deseninin çizgileri boyunca bir şey kullanmak mümkündür. Süper temiz veya okumak güzel değil ama işe yarıyor.

Misal:

protocol HuhThing {
  var huh: Int { get set }
}

func HuhMaker() -> HuhThing {
   class InnerHuh: HuhThing {
    var innerVal: Int = 0
    var huh: Int {
      get {
        return mysteriousMath(innerVal)
      }

      set {
       innerVal = newValue / 2
      }
    }

    func mysteriousMath(number: Int) -> Int {
      return number * 3 + 2
    }
  }

  return InnerHuh()
}

HuhMaker()
var h = HuhMaker()

h.huh      // 2
h.huh = 32 
h.huh      // 50
h.huh = 39
h.huh      // 59

innerVal ve mysteriousMath burada dış kullanımdan gizlidir ve nesneye doğru yolunuzu kazmaya çalışmak bir hataya neden olacaktır.

Swift belgelerini okumamın sadece bir parçasıyım, bu yüzden burada bir kusur varsa lütfen belirtin, bilmek isterim.


tamam, ben de bu çözümü düşündüm, ama açıkla, neden h.huh.innerVal ile erişemiyorum?
Sam

Swift tip güvenlidir ve dış dünyanın h hakkında bildikleri tek şey HuhThing'e uymasıdır. HuhThing, innerVal adı verilen bir özellik hakkında herhangi bir bilgi içermez ve bu nedenle ona erişmeye çalışmak bir hatadır.
Dave Kapp

8
Hala erişilebilir: Preflect(h)[0].1.value // 19
John Estropia

2
Orada güzel bulmak John - Ben yansıtmak farkında değildi. Nesneleri Tuples'a dönüştürmek gibi görünüyor - Swift'te bu işlev veya diğer metaprogramlama şeyleriyle ilgili resmi belgeler var mı? İBooks'ta dil kılavuzuna bir göz attım ama görmüyorum.
Dave Kapp

1
@JohnEstropia Yansımanın önemli olduğunu düşünmüyorum. Java (Daha dili olgun) olarak, orada olan erişim düzenleyiciler, ama onlar da yansıma hileler engellemez.
11684

10

Xcode 6 beta 4'ten itibaren Swift, erişim değiştiricilere sahiptir. Sürüm notlarından:

Hızlı erişim kontrolünün üç erişim seviyesi vardır:

  • özel varlıklara yalnızca tanımlandıkları kaynak dosyadan erişilebilir.
  • dahili varlıklara hedef içinde tanımlandıkları herhangi bir yerden erişilebilir.
  • kamu kuruluşlarına hedef içindeki herhangi bir yerden ve mevcut hedefin modülünü içe aktaran diğer herhangi bir bağlamdan erişilebilir.

Örtük varsayılan internal, bu nedenle bir uygulama hedefi içinde, daha kısıtlayıcı olmak istediğiniz yerler dışında erişim değiştiricileri kapalı bırakabilirsiniz. Bir çerçeve hedefinde (örneğin, bir uygulama ile bir paylaşım veya Bugün görünümü uzantısı arasında kod paylaşmak için bir çerçeve yerleştiriyorsanız), publicçerçevenizin istemcilerine göstermek istediğiniz API'yi belirtmek için kullanın .


Bu yanıt önceki Swift sürümlerinde geçerliydi, artık geçerli değil gibi görünüyor :) lütfen cevabımı kontrol et .
Ahmad F

6

Swift 3.0 beş farklı erişim kontrolü sağlar:

  1. açık
  2. halka açık
  3. fileprivate
  4. özel

Açık erişim ve genel erişim, varlıkların tanımlayıcı modüllerinden herhangi bir kaynak dosyada ve aynı zamanda tanımlayıcı modülü içe aktaran başka bir modülün kaynak dosyasında kullanılmasını sağlar. Bir çerçeveye genel arabirimi belirtirken genellikle açık veya genel erişimi kullanırsınız.

Dahili erişim, varlıkların tanımlayan modüllerinden herhangi bir kaynak dosyada kullanılmasına olanak tanır, ancak bu modülün dışındaki herhangi bir kaynak dosyada kullanılamaz. Dahili erişimi bir uygulamanın veya çerçevenin dahili yapısını tanımlarken kullanırsınız.

Dosya-özel erişim, bir varlığın kullanımını kendi tanımlayıcı kaynak dosyasıyla sınırlar. Bu ayrıntılar tüm dosyada kullanıldığında belirli bir işlev parçasının uygulama ayrıntılarını gizlemek için dosya-özel erişimini kullanın.

Özel erişim, bir kuruluşun kullanımını ekteki beyan ile sınırlar. Bu ayrıntılar yalnızca tek bir bildirimde kullanıldığında belirli bir işlevsellik parçasının uygulama ayrıntılarını gizlemek için özel erişimi kullanın.

Açık erişim en yüksek (en az kısıtlayıcı) erişim seviyesidir ve özel erişim en düşük (en kısıtlayıcı) erişim seviyesidir.

Varsayılan Erişim Seviyeleri

Kodunuzdaki tüm varlıklar (birkaç istisna dışında), kendiniz açık bir erişim düzeyi belirtmezseniz varsayılan bir dahili erişim düzeyine sahiptir. Sonuç olarak, çoğu durumda kodunuzda açık bir erişim düzeyi belirtmeniz gerekmez.

Konuyla ilgili sürüm notu:

Genel olarak bildirilen sınıflar artık tanımlayıcı modüllerinin dışında alt sınıflara ayrılamaz ve genel olarak bildirilen yöntemler artık tanımlayıcı modüllerinin dışında geçersiz kılınamaz. Bir sınıfın harici olarak alt sınıflara veya bir yöntemin harici olarak geçersiz kılınmasına izin vermek için, bunları açık olarak bildirin; bu, genelin ötesinde yeni bir erişim düzeyidir. İçe aktarılan Objective-C sınıfları ve yöntemlerinin tümü genel olarak değil, açık olarak içe aktarılır. @Testable içe aktarma kullanarak bir modülü içe aktaran birim testlerinin, genel veya dahili sınıfları alt sınıflara ayırmasına ve genel veya dahili yöntemleri geçersiz kılmasına izin verilir. (SE-0117)

Daha fazla bilgi ve detaylar: Hızlı Programlama Dili (Erişim Kontrolü)


Bu yanıt önceki Swift sürümlerinde geçerliydi, artık geçerli değil gibi görünüyor :) lütfen cevabımı kontrol et .
Ahmad F

4

Beta 6'da, belgeler üç farklı erişim değiştiricisinin olduğunu belirtmektedir:

  • halka açık
  • İç
  • Özel

Ve bu üçü Sınıflar, Protokoller, fonksiyonlar ve özellikler için geçerlidir.

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

Daha fazla bilgi için Erişim Denetimi'ni kontrol edin .


Daha fazla güvenlikle sınıf oluşturmayı kolaylaştıran korumalı bir değiştirici bulunmalıydı.
Kumar C

Bu yanıt önceki Swift sürümlerinde geçerliydi, artık geçerli değil gibi görünüyor :) lütfen cevabımı kontrol et .
Ahmad F

2

Şimdi beta 4'te Swift'e erişim değiştiricileri eklediler.

adlı Xcode 6 beta 4 realese notlar :

Hızlı erişim kontrolünün üç erişim seviyesi vardır:

  • private varlıklara yalnızca tanımlandıkları kaynak dosyasından erişilebilir.
  • internal varlıklara, hedef içinde tanımlandıkları herhangi bir yerden erişilebilir.
  • public varlıklara hedefin herhangi bir yerinden ve mevcut hedefin modülünü içe aktaran diğer herhangi bir bağlamdan erişilebilir.

Varsayılan olarak, kaynak dosyadaki varlıkların çoğu dahili erişime sahiptir. Bu, uygulama geliştiricilerinin erişim denetimini büyük ölçüde göz ardı etmesine olanak tanırken, çerçeve geliştiricilerinin bir çerçevenin API'sı üzerinde tam denetime izin verir.


Buna bir bağlantı gönderebilir misiniz?
Kardan Adam

Bu yanıt önceki Swift sürümlerinde geçerliydi, artık geçerli değil gibi görünüyor :) lütfen cevabımı kontrol et .
Ahmad F

2

Xcode 6'da tanıtıldığı gibi erişim kontrol mekanizmaları :

Swift, kodunuzdaki varlıklar için üç farklı erişim düzeyi sağlar. Bu erişim düzeyleri, bir varlığın tanımlandığı kaynak dosyaya ve ayrıca kaynak dosyanın ait olduğu modüle göredir.

  • Ortak erişim , varlıkların herhangi bir kaynak dosyada tanımlayıcı modüllerinden ve ayrıca tanımlayıcı modülü içe aktaran başka bir modülün kaynak dosyasında kullanılmasına olanak tanır. Genel çerçeveyi bir çerçeveye ortak arabirim belirtirken kullanırsınız.
  • Dahili erişim , varlıkların tanımlayan modüllerinden herhangi bir kaynak dosyada kullanılmasına olanak tanır, ancak bu modülün dışındaki herhangi bir kaynak dosyada kullanılamaz. Dahili erişimi bir uygulamanın veya çerçevenin dahili yapısını tanımlarken kullanırsınız.
  • Özel erişim , bir varlığın kullanımını kendi tanımlayıcı kaynak dosyasına kısıtlar. Belirli bir işlevin parçasının uygulama ayrıntılarını gizlemek için özel erişimi kullanın.

Genel erişim en yüksek (en az kısıtlayıcı) erişim düzeyidir ve özel erişim en düşük (veya en kısıtlayıcı) erişim düzeyidir.

Varsayılan , dahili olarak accecss ve bu nedenle belirtilmesi gerekmez. Ayrıca unutmayınız özel belirteci yapar değil sınıf düzeyinde çalışmalarını ancak kaynak dosya düzeyinde. Bu, bir sınıfın bölümlerini gerçekten özel hale getirmek için kendi dosyasına ayırmanız gerektiği anlamına gelir. Bu aynı zamanda birim testi ile ilgili bazı ilginç durumlar da ortaya koymaktadır ...

Benim yukarıda bahsettiğim bir diğer nokta da, yukarıdaki bağlantıda yorumlanmış olması, erişim seviyesini 'yükseltememeniz'. Bir şeyi alt sınıfa ayırırsanız, daha fazla kısıtlayabilirsiniz, ancak tam tersi olamaz.

Bu son bit de yani işlevi kullanıyorsa bu şekilde işlevlerini dizilerini ve mutlaka başka şeyler etkileyen özel sınıf, o zaman fonksiyon olması geçerli değil veya kamu erişim sahibi oldukları olmayabilir gibi özel sınıfa. Bu, derleyici uyarısı verir ve işlevi özel bir işlev olarak yeniden bildirmeniz gerekir .


Bu yanıt önceki Swift sürümlerinde geçerliydi, artık geçerli değil gibi görünüyor :) lütfen cevabımı kontrol et .
Ahmad F

2

Swift 3 ve 4 , değişkenlerin ve yöntemlerin erişim seviyeleri için de çok fazla değişiklik getirdi. Swift 3 ve 4 şimdi 4 farklı erişim seviyesine sahiptir, burada açık / genel erişim en yüksek (en az kısıtlayıcı) erişim seviyesidir ve özel erişim en düşük (en kısıtlayıcı) erişim seviyesidir:

  • özel işlevlere ve üyelere yalnızca kuruluşun kendisi (yapı, sınıf,…) ve uzantıları (Swift 3'te uzantılar da kısıtlanmıştır) içinden erişilebilir.
  • fileprivate işlevlerine ve üyelerine yalnızca bildirildikleri kaynak dosyadan erişilebilir.
  • dahili işlevlere ve üyelere (açıkça bir erişim düzeyi anahtar sözcüğü eklemezseniz varsayılan değerdir) hedef içinde tanımlandıkları herhangi bir yere erişilebilir. Bu nedenle TestTarget'ın tüm kaynaklara otomatik olarak erişimi yoktur, xCode'un dosya denetçisinde erişilebilir olarak işaretlenmeleri gerekir.
  • açık veya genel işlevlere ve üyelere hedef içindeki herhangi bir yerden ve geçerli hedefin modülünü içe aktaran diğer herhangi bir bağlamdan erişilebilir.

İlginç:

Her bir yöntemi veya üyeyi "özel" olarak işaretlemek yerine, bir sınıf / yapı uzantısında bazı yöntemleri (örneğin tipik olarak yardımcı işlevler) kapsayabilir ve tüm uzantıyı "Özel" olarak işaretleyebilirsiniz.

class foo { }

private extension foo {
    func somePrivateHelperFunction01() { }
    func somePrivateHelperFunction02() { }
    func somePrivateHelperFunction03() { }
}

Bu, daha iyi korunabilir kod elde etmek için iyi bir fikir olabilir. Ve sadece bir kelimeyi değiştirerek kolayca (örneğin birim testi için) özel olmayanlara geçebilirsiniz.

Apple belgeleri


Bu yanıt önceki Swift sürümlerinde geçerliydi, artık geçerli değil gibi görünüyor :) lütfen cevabımı kontrol et .
Ahmad F

2

Swift 1-3 için:

Hayır, bu mümkün değil. Hiç özel / korumalı yöntem ve değişken yoktur.

Her şey herkese açık.

Güncelleme Swift 4'ten beri, bu konudaki diğer cevapları görmek mümkün


1
Bu yorum mevcut tohum için doğrudur.
Jesper

2
Mevcut tohum için. Gelecekte görünecektir .
Jesper

1
"public" / "korumalı" / "private" şu anda mevcut değil, ancak kapanışları, protokolleri ve iç sınıfları kullanarak şeyleri gizleyebilirsiniz. Bunun nasıl yapılacağına dair bir örnek için lütfen cevabımdaki örnek koduma bakın. Nasıl çalıştığı konusunda yanılıyorsam ve örneğim yanlışsa, hala öğrenmeye devam ettiğim için lütfen bunu belirtin. :)
Dave Kapp

Görünüşe göre artık geçerli değil :) Lütfen cevabımı kontrol et .
Ahmad F

1

Kullanabileceğiniz seçeneklerden biri, örnek oluşturmayı bir işleve sarmak ve bir yapıcıda uygun alıcıları ve ayarlayıcıları sağlamaktır:

class Counter {
    let inc: () -> Int
    let dec: () -> Int

    init(start: Int) {
        var n = start

        inc = { ++n }
        dec = { --n }
    }
}


let c = Counter(start: 10)

c.inc()  // 11
c.inc()  // 12
c.dec()  // 11

0

Dil dilbilgisi anahtar kelimeler 'halkı', 'özel' veya 'korumalı' yoktur. Bu, her şeyin herkese açık olduğunu gösterir. Tabii ki, bu anahtar kelimeler olmadan erişim değiştiricileri belirtmek için alternatif bir yöntem olabilir, ancak bunu dil referansında bulamadım.


0

Umarım korunan yöntemlere benzer bir şey isteyenler için biraz zaman kazanırız:

Diğer cevaplara göre, swift artık Java veya C # gibi sınıf bilimi yerine dosya-bilimi olarak tanımlanan 'özel' değiştiriciyi sağlıyor. Bu, korunan yöntemler istiyorsanız , aynı dosyadaysa hızlı özel yöntemlerle yapabileceğiniz anlamına gelir

  1. 'Korunan' yöntemleri tutmak için bir temel sınıf oluşturun (aslında özel)
  2. Aynı yöntemleri kullanmak için bu sınıfı alt sınıfa ayırın
  3. Diğer dosyalarda, alt sınıfları da olsa, temel sınıf yöntemlerine erişemezsiniz.

örneğin Dosya 1:

class BaseClass {
    private func protectedMethod() {

    }
}

class SubClass : BaseClass {
    func publicMethod() {
        self.protectedMethod()  //this is ok as they are in same file
    }
}

Dosya 2:

func test() {
    var a = BaseClass()
    a.protectedMethod() //ERROR


    var b = SubClass()
    b.protectedMethod() //ERROR
}

class SubClass2 : BaseClass {
    func publicMethod() {
        self.protectedMethod() //ERROR
    }

}



-2

swift 2.0'a kadar sadece üç erişim seviyesi vardı [Genel, dahili, özel] ama swift 3.0 apple [Open, fileType] olan iki yeni erişim seviyesi ekledi, bu yüzden şimdi swift 3.0'da 5 erişim seviyesi var Burada rolü temizlemek istiyorum Açık: Bu Genel'e çok benzer, ancak tek fark, Halk'ın alt sınıfa erişip geçersiz kılabilmesi ve Açık erişim düzeyinin, bu görüntünün Orta web sitesinden alınmasına erişememesi ve bu farkı tanımlamasıdır. açık ve genel erişim arasında

Şimdi ikinci yeni erişim seviyesi 2. filetype özel veya daha az erişim seviyesinin dahili olandan daha büyük bir versiyonudur FileType [class, struct, enum] 'un genişletilmiş kısmına erişebilir ve private, yalnızca erişebileceği kodun genişletilmiş kısmına erişemez sözcük kapsamı bu görüntü Orta web sitesinden alınır ve bu filetype ve özel erişim seviyesi arasındaki farkı açıklamak

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.