Swift

[ Swift ] Class Singleton πŸ†š Struct Singleton

Forest Yun 2025. 1. 10. 09:19
728x90

 

 

μ‹±κΈ€ν„΄ νŒ¨ν„΄

μ‹±κΈ€ν„΄ νŒ¨ν„΄μ€ μ†Œν”„νŠΈμ›¨μ–΄ λ””μžμΈ νŒ¨ν„΄ 쀑 ν•˜λ‚˜λ‘œ, 단 ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œμ„ μ‚¬μš©ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€.

λ”°λΌμ„œ ν•œ 번 μƒμ„±λ˜λ©΄ κ·Έ λ©”λͺ¨λ¦¬ κ³΅κ°„λ§Œ 계속 μ‚¬μš©ν•˜λ―€λ‘œ λ©”λͺ¨λ¦¬ λ‚­λΉ„λ₯Ό λ°©μ§€ν•  수 있고, μ‚¬μš© μ‹œ 이미 μƒμ„±λ˜μ–΄ μžˆλŠ” μΈμŠ€ν„΄μŠ€ μ‚¬μš©ν•˜λŠ” 것이기 λ•Œλ¬Έμ— 속도도 λΉ λ¦…λ‹ˆλ‹€.

 

ν•˜μ§€λ§Œ μ „μ—­μ μœΌλ‘œ μƒμ„±λ˜μ–΄ λ§Žμ€ κ³³μ—μ„œ μ‚¬μš©λ˜λ―€λ‘œ μ—¬λŸ¬ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜λŠ” λ“±μ˜ λ©€ν‹°μŠ€λ ˆλ”© ν™˜κ²½μ—μ„œ λ™μ‹œμ„± λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€ν–‰νžˆ swiftμ—μ„œλŠ” μ΄ˆκΈ°ν™” μ‹œμ μ„ 미룬(lazily) static ν”„λ‘œνΌν‹°λ₯Ό 톡해 μΈμŠ€ν„΄μŠ€λ₯Ό thread-safetyν•˜κ²Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

The free function dispatch_once is no longer available in Swift. In Swift, you can use lazily initialized globals or static properties and get the same thread-safety and called-once guarantees as dispatch_once provided.

 

 

κ·ΈλŸΌμ—λ„ μ‹±κΈ€ν„΄ νŒ¨ν„΄ μ‚¬μš©μ€ μ‹ μ€‘ν•΄μ•Όν•©λ‹ˆλ‹€. 의쑴 관계상 κ΅¬μ²΄ν™”λœ ν΄λž˜μŠ€μ— μ˜μ‘΄ν•˜κ²Œ λ˜λ―€λ‘œ, 객체 μ§€ν–₯ 섀계 원칙에 μœ„λ°˜λ˜κ²Œ λ©λ‹ˆλ‹€.

객체 μ§€ν–₯ 섀계 원칙은 아직 곡뢀가 ν•„μš”ν•œ 뢀뢄이기 λ•Œλ¬Έμ— μ—¬κΈ°κΉŒμ§€λ§Œ μ •λ¦¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 

 

 

μ‹±κΈ€ν„΄ νŒ¨ν„΄ μ‚¬μš© μ˜ˆμ‹œ

iOSμ—μ„œλŠ” λ‹€μ–‘ν•œ κ³³μ—μ„œ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ΄ μ‚¬μš©λ˜κ³  있으며 μ‚¬μš©λ²•μœΌλ‘œ ꢌμž₯ν•˜κΈ°λ„ ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ CoreDataλ₯Ό μ‚¬μš© μ‹œ μ‹±κΈ€ν„΄ νŒ¨ν„΄μœΌλ‘œ CoreDataStack을 μƒμ„±ν•˜μ—¬ μ•± μ „μ—­μ—μ„œ CoreData을 톡해 데이터λ₯Ό μ‚¬μš©ν•˜λ„λ‘ μ œμ•ˆν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

// Define an observable class to encapsulate all Core Data-related functionality.
class CoreDataStack: ObservableObject {
    static let shared = CoreDataStack()  // ⭐️
    
    // Create a persistent container as a lazy variable to defer instantiation until its first use.
    lazy var persistentContainer: NSPersistentContainer = {
        
        // Pass the data model filename to the container’s initializer.
        let container = NSPersistentContainer(name: "DataModel")
        
        // Load any persistent stores, which creates a store if none exists.
        container.loadPersistentStores { _, error in
            if let error {
                // Handle the error appropriately. However, it's useful to use
                // `fatalError(_:file:line:)` during development.
                fatalError("Failed to load persistent stores: \(error.localizedDescription)")
            }
        }
        return container
    }()
        
    private init() { }
}

 

 

Setting up a Core Data stack | Apple Developer Documentation

Set up the classes that manage and persist your app’s objects.

developer.apple.com

 

 

 

 

 

 

Class Singleton πŸ†š Struct Singleton

μœ„ Apple의 예제 μ½”λ“œμ—μ„œλ„ μ•Œ 수 μžˆλ“―μ΄, μ‹±κΈ€ν„΄ νŒ¨ν„΄μ€ 클래슀λ₯Ό 톡해 κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ•Ό 단 ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ‘œ μ•± μ „μ—­μ—μ„œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 

ν΄λž˜μŠ€μ™€ ꡬ쑰체의 차이점으둜, κ°„λ‹¨ν•˜κ²Œ μ°Έμ‘° νƒ€μž…κ³Ό κ°’ νƒ€μž…μ„ λ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. μ‹±κΈ€ν„΄ νŒ¨ν„΄μ— ν΄λž˜μŠ€κ°€ μ‚¬μš©λ˜λŠ” μ΄μœ λ„ 이 μ°¨μ΄μ μ—μ„œ μ•Œμ•„λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

 

클래슀의 경우, μΈμŠ€ν„΄μŠ€ 생성 μ‹œ νž™ μ˜μ—­μ— λ©”λͺ¨λ¦¬κ°€ ν• λ‹Ήλ˜μ–΄ λ³€μˆ˜/μƒμˆ˜κ°€ 이 μΈμŠ€ν„΄μŠ€λ₯Ό κ°€λ¦¬ν‚€λŠ” λ°©μ‹μž…λ‹ˆλ‹€. λ”°λΌμ„œ A μΈμŠ€ν„΄μŠ€λ₯Ό κ°€λ¦¬ν‚€λŠ” `shared` λ³€μˆ˜κ°€ `a` λ³€μˆ˜μ— μžμ‹ μ„ ν• λ‹Ήν•˜λ©΄, μžμ‹ μ΄ κ°€μ§€κ³  있던 μΈμŠ€ν„΄μŠ€μ˜ μ£Όμ†Œ 값을 μ „λ‹¬ν•˜κ²Œ 되며 `shared` 와 `a` λ³€μˆ˜ λͺ¨λ‘ 같은 A μΈμŠ€ν„΄μŠ€λ₯Ό κ°€λ¦¬ν‚€κ²Œ λ©λ‹ˆλ‹€.

이와 λ°˜λŒ€λ‘œ ꡬ쑰체의 경우, μΈμŠ€ν„΄μŠ€ 생성 μ‹œ μŠ€νƒ μ˜μ—­μ— λ©”λͺ¨λ¦¬κ°€ ν• λ‹Ήλ˜μ–΄ λ³€μˆ˜/μƒμˆ˜κ°€ μΈμŠ€ν„΄μŠ€λ₯Ό κ°€μ§€κ³  μžˆλŠ” λ°©μ‹μž…λ‹ˆλ‹€. λ”°λΌμ„œ B-0 μΈμŠ€ν„΄μŠ€λ₯Ό κ°€μ§„ `shared` λ³€μˆ˜κ°€ `b` λ³€μˆ˜μ— μžμ‹ μ„ ν• λ‹Ήν•˜λ©΄ μƒˆλ‘œμš΄ B-1 μΈμŠ€ν„΄μŠ€ ν• λ‹Ήλ˜κ²Œ λ©λ‹ˆλ‹€. λ”°λΌμ„œ 각기 λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€λ₯Ό κ°–κ²Œ λ˜μ–΄ λ™μΌν•œ μΈμŠ€ν„΄μŠ€λ₯Ό μ‚¬μš©ν•΄ μ•± μ „μ—­μ—μ„œ 곡유 및 μ‚¬μš© ν•˜κ³ μž ν•˜λŠ” μ‹±κΈ€ν„΄ νŒ¨ν„΄μ˜ λͺ©μ μ„ 이루지 λͺ»ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

 

 

 

/*
 클래슀λ₯Ό μ‚¬μš©ν•œ μ‹±κΈ€ν„΄ νŒ¨ν„΄
 */

class SingletonWithClass {
    static let shared = SingletonWithClass()
    var value: Int = 10
    
    private init() {}
}

let a = SingletonWithClass.shared
a.value = 100

print("SingletonWithClass.shared", SingletonWithClass.shared.value)
print("a", a.value)

/*
 좜λ ₯
 SingletonWithClass.shared 100
 a 100
 */

 

// ꡬ쑰체λ₯Ό μ‚¬μš©ν•œ μ‹±κΈ€ν„΄ νŒ¨ν„΄

struct SingletonWithStruct {
    static let shared = SingletonWithStruct()
    var value: Int = 10
    
    private init() {}
}

var b = SingletonWithStruct.shared
b.value = 100

var c = SingletonWithStruct.shared
c.value = 200

print("SingletonWithStruct.shared", SingletonWithStruct.shared.value)
print("b", b.value)
print("c", c.value)


/*
 SingletonWithStruct.shared 10
 b 100
 c 200
 
 */

 

 

 

 

 

μ‹±κΈ€ν„΄ νŒ¨ν„΄μ˜ μž₯단점
thread-safetyν•œ 싱글톀 μ‚¬μš©
728x90

'Swift' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[ Swift ] μ—λŸ¬ 핸듀링  (0) 2025.02.12
[ iOS ]  (0) 2025.02.07
[ Swift ] Swiftλž€?  (0) 2023.10.08
[ Swift ] zip(_:_:)  (1) 2023.10.08
[ Swift ] isCase | isLowercase | isUppercase  (0) 2023.10.04