2017-12-20 6 views
1

Ich habe eine einfache Frage zu Singleton in schnellen, nach vieler Forschung, die ich nicht eine klare Antwort darauf gefunden. Also Frage ist - ich habe ein StructA:Verwendung selbst in Singleton struct

struct StructA { 
    static let shared = StructA() 

    private init() {} 

    public func someFuncA() { 
     //self.somefuncB() 
     //or 
     //StructA.shared.someFuncB() 
    } 

    private func someFuncB() { 

    } 
} 

I someFuncA aus anderen Klasse wie dieses StructA.shared.someFuncA() nennen:

  1. Können Sie mir bitte erklären, was der Unterschied self.somefuncB() und StructA.shared.someFuncB() (oben Code sehen)? Meiner Meinung nach gibt es keinen Unterschied, aber was ist, wenn ich einen solchen Code haben, wenn self.somefuncB() muss Rückruf aufgerufen werden -

  2. Also ich [weak self] verwenden müssen?

    public func someFuncA() { 
        someFuncWithCallback() { [weak self] in 
         self?.somefuncB() 
        } 
    } 
    

    oder kann ich nur schreiben

    public func someFuncA() { 
        someFuncWithCallback() { 
         StructA.shared.someFuncB() 
        } 
    } 
    

    ich diesen Code mit „Leaks“ geprüft (Xcode Instrumente) es sagt, dass es kein Leck ist, da ich weiß, näher/Block besitzt Objekte, die verwendet in Kann mir jemand erklären, was hier passiert? Vielen Dank.

+0

'self :: method' leitet statische Aufrufe weiter, während' Classname :: method' nicht – chandlerbing

+1

Da es nur eine Instanz eines Singletons geben kann, sind 'self.someFuncB' und' StructA.shared.someFuncB' äquivalent Selbst == StructA.shared; die Verwendung von "Selbst" wäre der einfachere und gebräuchlichere Ansatz. Ein Singleton kann nie veröffentlicht werden, also müssen Sie sich nicht um "schwache" Sorgen machen. – Paulw11

+0

@ Paulw11 Ich habe es! Sie können es als Antwort posten. –

Antwort

2

Ein paar Gedanken:

  1. A struct Singleton ist ein Widerspruch in sich. Ein Singleton ist ein Objekt, bei dem nur eine Instanz vorhanden sein sollte. Aber struct ist ein Werttyp und hat Speicher Semantik "kopieren". Bedenken Sie:

    var a = StructA.shared 
    a.foo = 42    // let's assume you had added a `var foo: Int` property to `StructA` 
    

    Die a ist eine Kopie des sogenannten Singleton, kein Hinweis auf sie. Die foo Eigenschaft wird in der Kopie festgelegt werden, aber nicht das Original „Singletons“. Um dieses Problem zu vermeiden, sollte der Singleton ein class, ein Referenztyp sein.

  2. Ich stimme mit Paulw11, dass self ist ein einfacher und gemeinsamer Ansatz. Ich würde auch vorschlagen, aber, dass self durch Verweisen Sie besseren Code schreiben können, die nicht abhängig von der Klasse ist ein Singleton sein.

  3. Da ich self Muster raten würde, würde ich daher auch offensichtlich Potential starke Referenzzyklen vorschlagen zu vermeiden (zum Beispiel durch weak oder unowned Referenzen beschäftigen, in denen erforderlich). Es macht keinen Sinn, wissentlich einen starken Referenzzyklus zu erstellen, einfach weil es ein Singleton ist. Warum schreiben Code, den Sie wissen, Sie würden neu zu schreiben, wenn Sie jemals die Entscheidung revisited Singletonmuster zu verwenden, vor allem, wenn Sie wissen, wie einfach es ist, starke Referenzen in erster Linie zu vermeiden?

  4. FYI, ich sehe das gleiche Verhalten, das Sie melden, dass, wenn ein static an einem theoretischen starken Referenzzyklus teilnimmt, es nicht als solches identifiziert wird. Aber wenn Sie festgelegt, dass static Eigenschaft auf nil (vorausgesetzt, es war variabel und optional), die starke Referenz erscheint.

    Diese Beobachtung ändert nichts an meiner obigen Empfehlung, nämlich zu vermeiden, was Sie wissen, wäre ein starker Referenzzyklus in irgendeinem anderen Kontext. Ich bestätige lediglich Ihre empirische Beobachtung.

In Bezug auf die Punkte 2 bis 4 oben (wo ich ein gewisses Potenzial eventuelle Refactoring von Singletonmuster in einem anderen Muster betrachten), sollte ich sagen, dass dies nicht eine rein akademische Beobachtung. Es ist nicht ungewöhnlich, einen Singleton-Typ zu haben, und später, wenn das Projekt komplizierter wird oder mehr Unit-Tests anwendet, um diese Entscheidung erneut zu prüfen und mit der Anwendung der Abhängigkeitsinjektion oder anderer Muster zu beginnen. Es wäre eine Schande, wenn Sie auch alle einzelnen Funktionen bearbeiten müssten. Wenn Sie den Code so schreiben, dass er nicht von der Singleton-Natur des Objekts abhängt, erhalten Sie eine robustere Codebasis mit weniger unnötigen internen Abhängigkeiten.

Verwandte Themen