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