이것이 "싱글 톤을 만드는 가장 좋은 방법"인지 묻습니다.
첫째, 이것은 스레드 안전 솔루션입니다. 이 dispatch_once
패턴은 Objective-C에서 싱글 톤을 생성하는 현대적이고 안전한 스레드 방식입니다. 걱정하지 마십시오.
그러나 이것이 최선의 방법인지 물었다. 그러나 싱글 톤과 함께 사용 하면 instancetype
및 [[self alloc] init]
오해의 가능성 이 있음을 인정해야합니다 .
instancetype
그것의 장점은 id
우리가 어제 해왔 던 것처럼 유형에 의지하지 않고 클래스를 서브 클래 싱 할 수 있음을 선언하는 명백한 방법이라는 것입니다 .
그러나이 static
방법에서는 서브 클래 싱 문제를 제시합니다. 자체 메소드 를 구현하지 않고 수퍼 클래스의 서브 클래스 인 경우 ImageCache
와 BlobCache
싱글 톤은 어떻습니까?Cache
sharedCache
ImageCache *imageCache = [ImageCache sharedCache]; // fine
BlobCache *blobCache = [BlobCache sharedCache]; // error; this will return the aforementioned ImageCache!!!
이것이 작동하기 위해서는 서브 클래스가 자신 만의 sharedInstance
(또는 특정 클래스에 대해 호출하는) 메소드를 구현해야 합니다.
결론적으로, 원본 sharedInstance
은 하위 클래스를 지원하는 것처럼 보이지만 그렇지 않습니다. 서브 클래 싱을 지원하려는 경우 최소한 미래 개발자에게이 방법을 재정의해야한다고 경고하는 설명서가 포함되어야합니다.
Swift와의 최상의 상호 운용성을 위해 클래스 메소드가 아닌 속성으로 정의하려는 경우가 있습니다. 예 :
@interface Foo : NSObject
@property (class, readonly, strong) Foo *sharedFoo;
@end
그런 다음이 속성에 대한 getter를 작성할 수 있습니다 (구현은 dispatch_once
제안한 패턴을 사용합니다 ).
+ (Foo *)sharedFoo { ... }
이것의 장점은 Swift 사용자가 그것을 사용하면 다음과 같이 할 수 있다는 것입니다.
let foo = Foo.shared
()
속성으로 구현했기 때문에 는 없습니다 . Swift 3부터는 싱글 톤에 일반적으로 액세스하는 방법이 있습니다. 따라서 속성으로 정의하면 상호 운용성을 촉진하는 데 도움이됩니다.
따로, Apple이 싱글 톤을 정의하는 방법을 살펴보면, 이것이 싱글턴을 정의한 패턴입니다. 예를 들어 NSURLSession
싱글 톤은 다음과 같이 정의됩니다.
@property (class, readonly, strong) NSURLSession *sharedSession;
매우 작은 스위프트 상호 운용성 고려 사항은 싱글 톤의 이름이었습니다. 유형이 아닌 이름을 통합 할 수있는 것이 가장 좋습니다 sharedInstance
. 예를 들어 클래스가 Foo
인 경우 singleton 속성을로 정의 할 수 있습니다 sharedFoo
. 또는 클래스가 있으면 DatabaseManager
속성을 호출 할 수 있습니다 sharedManager
. 그런 다음 Swift 사용자는 다음을 수행 할 수 있습니다.
let foo = Foo.shared
let manager = DatabaseManager.shared
분명히을 사용하려는 경우 언제든지 원하는 sharedInstance
스위프트 이름을 선언 할 수 있습니다.
@property (class, readonly, strong) Foo* sharedInstance NS_SWIFT_NAME(shared);
분명히 Objective-C 코드를 작성할 때 Swift 상호 운용성이 다른 디자인 고려 사항보다 중요하지는 않지만 두 언어를 정상적으로 지원하는 코드를 작성할 수 있다면 바람직합니다.
나는 당신이 원하는 경우,이 개발자가 / (실수로) 자신의 인스턴스의 인스턴스를 안 할 수없는 진정한 싱글로 지적 다른 사람과 동의 unavailable
에 관한 규정 init
하고 new
신중한이다.