WWDC 24์˜ Swift 6 migration guide๋ฅผ ์ •๋ฆฌํ•ด๋ณธ๋‹ค.

Queue ์‚ฌ์šฉ

Swift Concurrency

  • Swift Concurrency์—์„œ๋Š”, ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ Actor๋กœ ๋ณ€๊ฒฝํ•˜๊ณ ,
  • ๊ทธ ์‚ฌ์ด์—์„œ๋Š” thread safeํ•œ Value ํƒ€์ž…์„ ํ†ตํ•ด ํ†ต์‹ ํ•จ์œผ๋กœ์จ ๋ณด๋‹ค ๊ฐ„๊ฒฐํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋ฌธ์ œ

  • ๊ฐœ๋…์€ ์ข‹์œผ๋‚˜, ์ด๊ฑธ ์ด์ „ ์ฝ”๋“œ๋กœ๋ถ€ํ„ฐ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์ข€ ๋ถ€๋‹ด์ด ๋œ๋‹ค.
  • Data race๋ฅผ ํšŒํ”ผํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ.
  • Value type์œผ๋กœ ํ†ต์‹ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ๋„ ์•Œ๊ณ , actor๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ๋„ ์•ˆ๋‹ค.
  • ๊ทผ๋ฐ ๊ผญ ๊ทธ๋ ‡๊ฒŒ ํ•  ํ•„์š”๋Š” ์—†์—ˆ๋‹ค.
  • ์ฆ‰, @Sendableํ•˜์ง€ ์•Š์€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๊ดœ์ฐฎ์•˜๋‹ค.
  • ์ด๋ ‡๊ฒŒ Tightํ•˜๊ฒŒ ์žกํ˜€์žˆ์ง€ ์•Š๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ๋‹ค์Œ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์†Œ์ง€๊ฐ€ ์žˆ๋‹ค.
    1. Crash๋กœ ์ธํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์ €ํ•ด
    2. ๋ฐ์ดํ„ฐ ๋ถ€ํŒจ

๋ฐฉํ–ฅ

๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ๋ฅผ ๊ฐ•์ œํ•˜๊ฒ ๋‹ค. (Enforcement of data isolation)

  • thread safeํ•˜์ง€ ๋ชปํ•œ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์ด๋ฅผ ์ฒดํฌํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋„๋ก ๋งŒ๋“ค๊ฒ ๋‹ค.
  • ์ด์ œ๋ถ€ํ„ฐ๋Š” ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, Multi thread ํ™˜๊ฒฝ์„ ๊ณ ๋ คํ•˜๋ฉฐ ์–ด๋””์„œ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœ๋  ๊ฒƒ์ธ์ง€๋„ ์—ผ๋‘์— ๋‘๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ผ.
  • ํŠน์ • ํƒ€์ž…์ด ์–ด๋–ป๊ฒŒ Multi thread ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ์ œ์•ฝํ•˜์—ฌ โ€œLocal reasoning(ํŠน์ • ์†Œ์Šค์ฝ”๋“œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋™์ž‘์„ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์„ฑ)โ€œ์„ ๋†’์ด๊ฒ ๋‹ค.

Global Variable

  • ์ „์—ญ ๋ณ€์ˆ˜๋Š” data race๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์šด ์กฐ๊ฑด์ด๋‹ค.
  • ์ด๋Ÿฐ ๊ฒฝ์šฐ let์œผ๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ผ๋‹จ ํ•ด๊ฒฐ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
    • (ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ Sendable์ด๋ผ๋ฉด)
let logger = Logger()
  • ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ํ•ด๋‹น ๊ฐ’์„ ๋‚˜์ค‘์— ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์–ด๋–จ๊นŒ?
  • ์ฆ‰, var๋กœ ์„ ์–ธํ•˜๋ฉด์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?
  • ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ Global Actor๋กœ ์„ ์–ธํ•˜๋ฉด ๋œ๋‹ค.
    • @MainActor keyword๋Š” Global Actor์˜ ์ผ์ข…์ด๋‹ค.
  • ์ „์—ญ์—์„œ Actor์™€ ๊ฐ™์ด ๋™์ž‘ํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
@MainActor var logger = Logger()
  • ๋•Œ๋กœ๋Š” ์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋‚ฌ์„ ๋•Œ, Actor์™€ ๊ฐ™์€ ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ€๋ น, ํ•ด๋‹น ๋ณ€์ˆ˜์˜ data race ๋ฌธ์ œ๋ฅผ lock, semaphore, dispatch queue์™€ ๊ฐ™์€ ๋กœ์ง์œผ๋กœ ์ฒ˜๋ฆฌํ–ˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค.
  • ๊ทธ๋ž˜์„œ ๊ตณ์ด swift concurrency๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์ด๋Ÿฐ ๊ฒฝ์šฐ nonisolated(unsafe) ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋œ๋‹ค.
nonisolated(unsafe) var logger = Logger()
  • Lazy Initialization์— ๋Œ€ํ•œ ๋ฌธ์ œ๋Š” ์—†๋‚˜?
  • Swift๋Š” Lazy Initialization์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ดˆ๊ธฐ์— ๋‘๊ฐœ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ์—์„œ ๋™์‹œ์ ‘๊ทผํ–ˆ์„ ๋•Œ์˜ ๋ฌธ์ œ๋Š” ์—†์„๊นŒ?
  • Swift๋Š” ์ „์—ญ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด mutual exclusive๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ดœ์ฐฎ๋‹ค.

Delegate

  • ์‹œ์Šคํ…œ์—์„œ ์ œ๊ณตํ•˜๋Š” Delegate๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž.
  • iOS์—๋Š” ๋‹ค์–‘ํ•œ delegate๋“ค์ด ์žˆ๋Š”๋ฐ, ํ•ด๋‹น ๋ฌธ์„œ์— ๊ฐ€๋ณด๋ฉด delegate์˜ call back์„ ์–ด๋Š ์Šค๋ ˆ๋“œ๋กœ ์ฃผ๋Š”์ง€์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.
  • ์ฝ”๋“œ๋งŒ ์ถ”์ ํ•ด์„œ ๋ณด์•„์„œ๋Š” ํ•ด๋‹น delegate๊ฐ€ ์–ด๋Š ์Šค๋ ˆ๋“œ๋กœ callback์„ ์ค„์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.
  • ์ด๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด ์ œ๋Œ€๋กœ๋œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ฌธ์„œ๋ฅผ ์ฐพ๊ณ , ๋‹ค์‹œ ์ด๋ฅผ ๋ฐ˜์˜ํ•˜๊ณ ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ์ง“์„ ํ•ด์•ผ ํ•œ๋‹ค.
  • ์ž˜๋ชปํ•˜๋ฉด data race๋ฅผ ์ผ์œผํ‚ค๊ธฐ๋„ ์‰ฝ๋‹ค.
  • ์‹œ์Šคํ…œ์—์„œ call back ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋ผ๋„ ๋ฐ”๊ฟ”๋ฒ„๋ฆฌ๋ฉด, ๋‚ด ์ฝ”๋“œ๊ฐ€ ๋ฌด๋„ˆ์ง€๊ธฐ๋„ ์‰ฝ๋‹ค.
  • Swift์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋ณด์žฅ์˜ ๋ถ€์กฑ ํ˜„์ƒ์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ”๊ฟจ๋‹ค.

Example

  • ๋งŒ์•ฝ ํŠน์ • delegate๊ฐ€ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋Š” thread๊ฐ€ Main์ด์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.
@MainActor
public protocol AADelegate {
						
}
  • Main ๋ง๊ณ  ๋‚ด๊ฐ€ ์ •ํ•œ ๋‹ค๋ฅธ ์‹คํ–‰ํ๋ฆ„์—์„œ๋งŒ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. (Global Actor)
@SomeActor
public protocol AADelegate {
							
}
  • ๊ทธ๋Ÿผ ์•„๋ฌด๊ฒƒ๋„ ๋‹ฌ์ง€ ์•Š์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?
public protocol AADelegate {
							
}
  • ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•˜์œ„์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋‘ nonisolatedํ•˜๋‹ค๊ณ  ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ์ฆ‰, ์–ด๋–ค ์Šค๋ ˆ๋“œ์—์„œ ๋™์ž‘ํ•ด๋„ ๊ดœ์ฐฎ์•„~ ๋ผ๊ณ  ์ฒ˜๋ฆฌํ•ด๋ฒ„๋ฆฐ๋‹ค.

๊ฒช์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋“ค

  • ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด ์žˆ๋‹ค๊ณ  ํ•˜์ž.
public protocol CaffeineThresholdDelegate: AnyObject {
	func caffeineLevel(at level: Double)
}
@MainActor
class Recaffeinater: ObservableObject {
    @Published var recaffeinate: Bool = false
    var minimumCaffeine: Double = 0.0
}
 
extension Recaffeinater: CaffeineThresholdDelegate {
	// ERROR!
    public func caffeineLevel(at level: Double) {
        if level < minimumCaffeine {
            // TODO: alert user to drink more coffee!
        }
    }
}
  • ์œ„ ์ƒํ™ฉ์ด๋ผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.
  • delegate์— thread์— ๋Œ€ํ•œ ์ œ์•ฝ์„ ๊ฑธ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— nonisolatedํ•˜๋‹ค๊ณ  ์ฒ˜๋ฆฌํ–ˆ๊ณ ,
  • Recaffeinater์˜ ๊ฒฝ์šฐ์—๋Š” ํ•˜์œ„ ๋ชจ๋“  property์™€ method์˜ ์‹คํ–‰ thread๋ฅผ main์—์„œ ํ•˜๊ฒ ๋‹ค ํ–ˆ์œผ๋‹ˆ, ์ถฉ๋Œ์ด ๋‚œ ๊ฒƒ.

ํ•ด๊ฒฐ 1

extension Recaffeinater: CaffeineThresholdDelegate {
    nonisolated public func caffeineLevel(at level: Double) {
        if level < minimumCaffeine { // ERROR!
            
        }
    }
}
  • delegate์˜ ์š”์ฒญ์‚ฌํ•ญ์— ๋งž์ถฐ, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” main์—์„œ ๊ฒฉ๋ฆฌ๋˜์–ด ์‹คํ–‰๋จ์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋„๋ก ๋ฐ”๊ฟ”๋ฒ„๋ฆฐ๋‹ค.
  • ๊ทผ๋ฐ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, 4๋ฒˆ ๋ผ์ธ์—์„œ ๋‚ด๊ฐ€ ํ•ด์•ผํ•˜๋Š” ๋™์ž‘์ธ UI ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์—†๋‹ค.
  • main thread์—์„œ ๋™์ž‘ํ•ด์•ผ ํ•˜๋‹ˆ๊นŒ.
  • ๋Œ€ํ‘œ์ ์œผ๋กœ minimunCaffeine๋ณ€์ˆ˜๊ฐ€ @MainActor๋ผ์„œ 3๋ฒˆ ๋ผ์ธ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.
nonisolated public func caffeineLevel(at level: Double) {
    Task { @MainActor in
      if level < minimumCaffeine {
        // TODO: alert user to drink more coffee!
    	}
    }
}
  • ๊ทธ๋Ÿผ ์ด๋Ÿฌํ•œ ๋ชจ์–‘์ด ๋˜๊ฒ ๋‹ค.
  • ์‚ฌ์‹ค ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ณด๋‹ค๋Š” CaffeineThresholdDelegate๊ฐ€ ์ •๋ง non isolated ํ™˜๊ฒฝ์—์„œ๋งŒ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด ๋” ์˜ณ์„ ๊ฒƒ์ด๋‹ค.

ํ•ด๊ฒฐ 2

  • CaffeineThresholdDelegate๋ฅผ MainActor์—์„œ ํ˜ธ์ถœํ•˜๋„๋ก ์ œํ•œํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํ•˜์ž.
  • SDK์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฑฐ๋ผ ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ์†๋ณผ์ˆ˜๊ฐ€ ์—†๋‹ค๊ณ  ์น˜์ž.
nonisolated public func caffeineLevel(at level: Double) {
    MainActor.assumeIsolated {
        if level < minimumCaffeine {
            // TODO: alert user to drink more coffee!
        }
    }
}
 
  • ๊ทธ๋Ÿผ ์ด๋ ‡๊ฒŒ๋„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • delegate์—์„œ ์˜ค๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์•Œ ์ˆ˜ ์—†๋‹ค๊ณ ?
  • ๊ทธ๋Ÿผ main์—์„œ ์˜ค๋Š” ๊ฒฝ์šฐ๋งŒ ์ฒ˜๋ฆฌํ•˜์ž. / ํ˜น์€ main์—์„œ ์˜ฌ ๊ฒƒ์„ ๋ฏฟ๊ณ  ์œ„์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌํ•˜์ž.
  • ํ˜น์‹œ๋ผ๋„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์˜ฌ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด assert๊ฐ™์€ ๊ฑธ๋กœ ๋Œ€๋น„ํ•˜๋ฉด ์ข‹๊ฒ ๋‹ค.
  • ์ด๋ ‡๊ฒŒ callback์— ๋Œ€ํ•œ ๋ฏฟ์Œ(?)์˜ ์˜์—ญ์œผ๋กœ ๊ฐ€๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋ชจ๋‘ ์œ„์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•  ์ˆ˜๋Š” ์—†์œผ๋ฏ€๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ œ๊ณตํ•œ๋‹ค.
    • ํ˜น์€ swift concurrency๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•œ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•œ ํ‚ค์›Œ๋“œ๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค.
extension Recaffeinater: @preconcurrency CaffeineThresholdDelegate {
    public func caffeineLevel(at level: Double) {
        if level < minimumCaffeine {
            // TODO: alert user to drink more coffee!
        }
    }
}
  • @preconcurrency๋Š” ๊ธฐ์กด ์ฝ”๋“œ๊ฐ€ ๋™์‹œ์„ฑ ๋ชจ๋ธ ๊ทœ์น™์„ ๋”ฐ๋ฅด์ง€ ์•Š์•„๋„ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ํ‚ค์›Œ๋“œ๋‹ค.
  • ์ฆ‰, ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ฅผ ๋ฏฟ์œผ๋ผ๋Š” ํ‚ค์›Œ๋“œ.
  • ์ถ”ํ›„์— CaffeineThresholdDelegate๊ฐ€ MainActor์ด์–ด์•ผ ํ•œ๋‹ค๋Š” ์ œ์•ฝ์ด ์ถ”๊ฐ€๋œ๋‹ค๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋”์ด์ƒ @preconcurrency๊ฐ€ ํ•„์š”์—†๋‹ค๋Š” ๊ฒฝ๊ณ ๋ฅผ ๋‚ ๋ ค์ค€๋‹ค.

Donโ€™t Panic

  • ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๊ต‰์žฅํžˆ ๋งŽ์€ ๊ฒฝ๊ณ ๊ฐ€ ๋œฐ๊ฑฐ๋‹ค.
  • ์ซ„์ง€๋งˆ๋ผ (?)
  • let์„ ์–ธ๊ณผ ๊ฐ™์ด ์‰ฌ์šด ๋ณ€๊ฒฝ๋„ ์žˆ์„ ๊ฒƒ์ด๊ณ ,
  • ํŠน์ • ํด๋ž˜์Šค ์ž์ฒด์— @MainActor์„ ์–ธ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•œ ๋ณ€๊ฒฝ์œผ๋กœ ๋งŽ์€ ๊ฒฝ๊ณ ๋ฅผ ์ง€์šธ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
  • ์ฆ‰, ๋Œ€๋‹ค์ˆ˜์˜ ์‰ฌ์šด ๋ฌธ์ œ + ์–ด๋ ค์šด ์•ฝ๊ฐ„์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๋‹ค. (๊ณผ์—ฐ?)

Actor๊ฐ„์˜ ํ†ต์‹ 

  • ํŠน์ • C ๊ฐ์ฒด์˜ ๋ฐฐ์—ด์„ A actor์—์„œ B actor๋กœ ๋ณด๋‚ธ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?
  • C ๊ฐ์ฒด๋Š” Sendable์„ ์ค€์ˆ˜ํ•ด์•ผ ํ•œ๋‹ค.

ACL์— ๋”ฐ๋ฅธ sendability inference

  • A, B Actor๊ฐ€ ํŠน์ • framework ๋‚ด๋ถ€์— ์žˆ๊ณ ,
  • ์ „๋‹ฌ๋˜๋Š” C ํƒ€์ž…์ด internal๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค๋ฉด,
  • Swift๋Š” struct์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ Sendable์„ ์ถ”๋ก ํ•ด์„œ ์ ์šฉํ•œ๋‹ค.
  • ํ•˜์ง€๋งŒ publicํƒ€์ž…์— ๋Œ€ํ•ด์„œ๋Š” ์ž๋™ ์ ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • public์ด๋ž€ ์˜๋ฏธ๋Š”, ๊ณง ํ•ด๋‹น framework๋ฅผ ์‚ฌ์šฉํ•˜๋Š” client๊ฐ€ ์žˆ๋‹ค๋Š” ๋œป์ด๊ณ ,
  • ๊ทธ๋“ค์—๊ฒŒ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋งŒ์•ฝ C ํƒ€์ž…์— Sendable์ด๋ผ๋Š” ๊ฒƒ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ฑ„ํƒํ•˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์—์„œ client๊ฐ€ Cํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด,
  • ํ•ด๋‹น ๊ฐ’์ด ๋ณ€ํ•˜๋Š”์ง€ ๊ทธ๋ ‡์ง€ ์•Š์€์ง€๋ฅผ ์ผ์ผํžˆ ์‚ดํŽด๋ด์•ผ ํ•œ๋‹ค.
// Client: Sendable์ธ์ง€์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์—†์Œ
public struct C {
	public let apple: String
}
 
  • (์ด๋Ÿฐ ๋ฌธ์ œ๋กœ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒ๋จน์ง€ ๋งˆ๋ผ๊ณ  ํ•œ ๊ฒƒ)

Objective C ํƒ€์ž…์ด๋ฉด ์–ด๋–กํ•˜์ง€?

  • ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ํƒ€์ž…์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ๋‹ค.
  • ๋งŒ์•ฝ์— Objective-C ํƒ€์ž…์„ ๋ฐ”๊นฅ์œผ๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ฉด ์–ด์ฉŒ์ง€?
  • Reference Type์ธ๋ฐ ๋ง์ด๋‹ค.

์˜๋ฏธ์ ์œผ๋กœ ์•ˆ์ „ํ•˜๋‹ค๋ฉด..

  • ํ•ญ์ƒ copy๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋œ ํƒ€์ž…์ผ ์ˆ˜ ์žˆ๋‹ค.
  • NSCopying์— ์˜ํ•ด ๋ณต์‚ฌ๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ›๋Š” ๋‹ค๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋œ๋‹ค๋ฉด,
  • Sendable์ด ์•„๋‹์ง€๋ผ๋„ ์˜๋ฏธ์ ์œผ๋กœ ๋ณดํ˜ธํ•œ ๋’ค, ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • nonisolated(unsafe) ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
    • ๊ฒฐ๊ตญ ์ด๊ฑด ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์—ญ๋Ÿ‰์— ๋งก๊ธฐ๋Š” ์˜ต์…˜์ด๋‹ค.
// Client: Sendable์ธ์ง€์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์—†์Œ
public struct C {
	public let apple: String
	
	nonisolated(unsafe)
	public let melon: SomeObjectiveClass
}
 

Wrap-up

  1. ์ฒœ์ฒœํžˆ ํ•ด๋ผ.
  2. ๊ฐ„๋‹จํ•œ ๊ฒƒ ๋ถ€ํ„ฐ ์ฒ˜๋ฆฌํ•˜์ž.
  3. ๋ฆฌํŒฉํ† ๋ง ํ•ด์•ผํ•  ๊ฒƒ์ด๋‹ค.
  4. Migrating to Swift 6๋ฅผ ์ฐธ๊ณ ํ•ด๋ผ.

์˜ˆ์ƒ๋˜๋Š” ๋ฌธ์ œ์ 

Annotation ์ „ํŒŒ์˜ ๋ฌธ์ œ

  • ํŠน์ • ์‹œ์Šคํ…œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.
  • ์ด์ „์—๋Š” my function์ด ์žˆ๋Š” class์—์„œ ๊ทธ๋ƒฅ ์‚ฌ์šฉํ–ˆ์œผ๋ฉด ๋๋‹ค.

  • ๊ทธ๋Ÿฐ๋ฐ swift ๋ฒ„์ „์ด ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ ํŠน์ • ๋ฉ”์„œ๋“œ ์ž์ฒด๊ฐ€ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ œ์•ฝ๋œ๋‹ค๋ฉด,
  • ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋“ค์—์„œ๋„ ์–ด๋–ค ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰์ด ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ๋ช…์‹œ์ ์œผ๋กœ ๊ฒฐ์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

Reference