Bunun "singleton oluşturmanın en iyi yolu" olup olmadığını soruyorsunuz.
İlk olarak, evet, bu iş parçacığı için güvenli bir çözümdür. Bu dispatch_oncemodel Objective-C'de tek ton üretmenin modern, iş parçacığı açısından güvenli bir yoludur. Endişeye gerek yok.
Yine de, bunu yapmanın "en iyi" yolu olup olmadığını sordunuz. Ancak şunu kabul etmeliyiz ki instancetypeve[[self alloc] init] birlikte, tekillerle birlikte kullanıldığında potansiyel olarak yanıltıcı .
Bunun yararı instancetype, sınıfın, iddün yaptığımız gibi bir tür başvurmadan alt sınıflara ayrılabileceğini açıklamanın açık bir yoludur .
Ancak staticbu yöntemde alt sınıflandırma zorlukları ortaya çıkar. Ya ImageCacheve BlobCachesingletonların her ikisi de Cachekendi sharedCacheyöntemlerini uygulamadan bir üst sınıftan alt sınıflarsa ?
ImageCache *imageCache = [ImageCache sharedCache]; // fine
BlobCache *blobCache = [BlobCache sharedCache]; // error; this will return the aforementioned ImageCache!!!
Bunun işe yaraması için, alt sınıfların kendi sharedInstance(veya kendi sınıfınız için ne derseniz söyleyin) yöntemini uyguladığından emin olmanız gerekir.
Alt satırda, orijinaliniz alt sınıfları destekleyecek gibi sharedInstance görünüyor , ancak olmayacak. Alt sınıflamayı desteklemek istiyorsanız, en azından gelecekteki geliştiricileri bu yöntemi geçersiz kılmaları konusunda uyaran belgeleri ekleyin.
Swift ile en iyi birlikte çalışabilirlik için, muhtemelen bunu bir sınıf yöntemi değil, bir özellik olarak tanımlamak istersiniz, örneğin:
@interface Foo : NSObject
@property (class, readonly, strong) Foo *sharedFoo;
@end
Sonra devam edip bu özellik için bir alıcı yazabilirsiniz (uygulama dispatch_onceönerdiğiniz kalıbı kullanır ):
+ (Foo *)sharedFoo { ... }
Bunun yararı, bir Swift kullanıcısı kullanmaya başlarsa, şöyle bir şey yapmalarıdır:
let foo = Foo.shared
Not, hayır (), çünkü onu bir özellik olarak uyguladık. Swift 3'ten başlayarak, genellikle tektonlara bu şekilde erişilir. Dolayısıyla onu bir özellik olarak tanımlamak, birlikte çalışabilirliği kolaylaştırmaya yardımcı olur.
Bir kenara, Apple'ın kendi tektonlarını nasıl tanımladığına bakarsanız, bu benimsedikleri kalıptır, örneğin NSURLSessiontekilleri aşağıdaki gibi tanımlanır:
@property (class, readonly, strong) NSURLSession *sharedSession;
Swift ile birlikte çalışabilirlik konusundaki bir diğer önemli husus, singleton'un adıydı. Bunun yerine türün adını dahil edebiliyorsanız en iyisidir sharedInstance. Örneğin, sınıf buysa Foo, singleton özelliğini olarak tanımlayabilirsiniz sharedFoo. Veya sınıf olsaydı DatabaseManager, özelliği çağırabilirsiniz sharedManager. Ardından Swift kullanıcıları şunları yapabilir:
let foo = Foo.shared
let manager = DatabaseManager.shared
Açıkçası, gerçekten kullanmak istiyorsanız sharedInstance, istediğiniz zaman Swift adını her zaman bildirebilirsiniz:
@property (class, readonly, strong) Foo* sharedInstance NS_SWIFT_NAME(shared);
Açıkça, Objective-C kodu yazarken, Swift birlikte çalışabilirliğinin diğer tasarım hususlarından daha ağır basmasına izin vermemeliyiz, ancak yine de, her iki dili de zarif bir şekilde destekleyen bir kod yazabilirsek, bu tercih edilir.
Bunun, geliştiricilerin kendi örneklerini (yanlışlıkla) somutlaştıramayacağı / kazaramayacağı gerçek bir singleton olmasını istiyorsanız, unavailableniteleyicinin initve newihtiyatlı olduğuna dikkat çeken diğerlerine katılıyorum .