<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>iOYES</title>
    <link>https://green1229.tistory.com/</link>
    <description>Green is Green </description>
    <language>ko</language>
    <pubDate>Tue, 21 Jul 2026 02:44:04 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>GREEN.1229</managingEditor>
    <image>
      <title>iOYES</title>
      <url>https://tistory1.daumcdn.net/tistory/4326025/attach/5dc0ba3d4d3c460d8c291fa6a8cfb2d1</url>
      <link>https://green1229.tistory.com</link>
    </image>
    <item>
      <title>[SE-0532] Optional noncopyable improvements and generalizations</title>
      <link>https://green1229.tistory.com/629</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이번 포스팅에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;SE-0532 &amp;mdash; Optional noncopyable 개선 및 일반화&lt;/b&gt;&lt;/span&gt;에 대해 정리해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;12313.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beTn2H/dJMcaccNloH/VWFh2ipFVLu7KUxK67ZMzk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beTn2H/dJMcaccNloH/VWFh2ipFVLu7KUxK67ZMzk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beTn2H/dJMcaccNloH/VWFh2ipFVLu7KUxK67ZMzk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeTn2H%2FdJMcaccNloH%2FVWFh2ipFVLu7KUxK67ZMzk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;12313.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Intro&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;div style=&quot;background: #f2f8ee; border-radius: 10px; padding: 16px 20px; margin: 16px 0;&quot;&gt;
&lt;p style=&quot;margin: 4px 0;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Proposal:&lt;/b&gt; SE-0532&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 4px 0;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Author:&lt;/b&gt; Alejandro Alonso&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 4px 0;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Review Manager:&lt;/b&gt; John McCall&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 4px 0;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Status:&lt;/b&gt; Accepted&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 4px 0;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Implementation:&lt;/b&gt; swiftlang/swift#88505&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Motivation&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Swift 6.0에서 표준 라이브러리 일부가 noncopyable 값을 저장할 수 있도록 일반화된 이후&lt;/b&gt;(SE-0437), &lt;b&gt;noncopyable optional을 다루는 일은 꽤 번거로웠습니다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;optional 내부 값을 살짝 들여다보고 싶은 것뿐인데, borrow만 하고 싶을 때도 마땅한 방법이 없었거든요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래 코드를 볼까요?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;if let payload = optional {
  
}

foo(optional) // error: use after consume!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다행히 &lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0432-noncopyable-switch.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;noncopyable switch&lt;/a&gt;를 쓰면 optional의 내용을 borrow하도록 제어 흐름을 만들 수 있습니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;switch optional {
case .some(let wrapped):
  // wrapped는 borrow된 상태

default:
  break
}

foo(optional) // ok&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 &lt;code&gt;if let&lt;/code&gt;이나 &lt;code&gt;guard let&lt;/code&gt;에 익숙한 사람이라면 이 switch 문이 그리 직관적이진 않죠  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;값을 consume하지 않고 mutate만 하고 싶은 경우도 마찬가지예요. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단순한 프로퍼티 변경이나 mutating 메서드 호출 정도는 &lt;code&gt;?.&lt;/code&gt; 체이닝으로 충분하지만, payload를 조건부로 &lt;code&gt;inout&lt;/code&gt; 함수에 넘기고 싶다면 이렇게 써야 합니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;isbl&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;if someStruct.x != nil {
  foo(&amp;amp;someStruct.x!)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;혹은 switch로 consume한 뒤 다시 초기화하는, 더 장황하고 직관적이지 않은 방식을 써야 하죠.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;func foo(_: inout NoncopyableString) {}

func bar(_ x: inout NoncopyableString?) {
  switch consume x {
  case .some(var string):
    foo(&amp;amp;string)
    x = consume string

  default:
    x = nil
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기에 더해 &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;unsafelyUnwrapped&lt;/code&gt; 같은 &lt;code&gt;Optional&lt;/code&gt; API들도 noncopyable 래핑 타입에는 지원되지 않아서, 이런 코드를 매번 switch 문으로 직접 풀어써야 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Proposed Solution&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;Optional&lt;/code&gt;에 새로운 프로퍼티 두 개, &lt;code&gt;ref&lt;/code&gt;와 &lt;code&gt;mutableRef&lt;/code&gt;를 추가합니다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 프로퍼티들은 내부 payload가 있으면 그 참조를, 없으면 &lt;code&gt;nil&lt;/code&gt;을 돌려줍니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;func bar(_ x: borrowing SomeNoncopyable) {
  ...
}

if let payload = optional.ref {
  bar(payload.value) // 'bar'는 'borrowing Wrapped'를 전달받음
}

foo(optional) // ok&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;func baz(_ x: inout SomeNoncopyable) {
  ...
}

if var payload = optional.mutableRef {
  baz(&amp;amp;payload.value) // 'baz'가 payload를 그 자리에서 mutate 가능!
}

foo(optional) // ok&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 두 프로퍼티 덕분에 &lt;b&gt;optional의 소유권을 가져오지 않고도 내부 값에 조건부로 접근하는 관용적인 방법&lt;/b&gt;이 생겼습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;더불어 아래 세 메서드도 noncopyable / nonescapable 래핑 타입을 지원하도록 일반화됩니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;map&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;flatMap&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;unsafelyUnwrapped&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;vim&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;let optAtomicInt: Optional&amp;lt;Atomic&amp;gt; = ...
let optInt: Optional = optAtomicInt.map {
  $0.load(ordering: .relaxed)
}

let optInlineArray: Optional&amp;lt;[0 of Atomic]&amp;gt; = []
let optInt2: Optional = optInlineArray.flatMap {
  $0.isEmpty ? nil : $0[0].load(ordering: .relaxed)
}

let optMutex: Optional&amp;lt;Mutex&amp;gt; = ...
let mutex: Mutex = optMutex.unsafelyUnwrapped
optMutex?.withLock { ... } // error: use of 'optMutex' after consume&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;마지막으로 &lt;code&gt;Optional.put()&lt;/code&gt;이라는 편의 API도 추가돼요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래처럼 &lt;code&gt;!&lt;/code&gt;로 강제 언래핑하던 패턴을 생각해볼게요.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;lasso&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;struct Cache: ~Copyable {
  var opt: UniqueArray?
}

var cache = Cache()
var items: UniqueArray = fooBar()
cache.opt = items

let newItem = await retrieveNewItem()
cache.opt!.append(newItem)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;border-left: 4px solid #3a8c28; background: #f2f8ee; padding: 8px 16px; margin: 16px 0;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이미 값이 있다는 걸 알고 있는 상황이라 &lt;code&gt;!&lt;/code&gt;가 사실 불필요하고, inline되지 않는 함수를 거치는 경우엔 컴파일러가 최적화해서 없애주지도 못해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;put()&lt;/code&gt;은 새 값을 넣어주면서 그 payload에 대한 direct mutable reference를 바로 돌려줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;lasso&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;struct Cache: ~Copyable {
  var opt: UniqueArray?
}

var cache = Cache()
let items: UniqueArray = fooBar()
var itemsRef = cache.opt.put(items)

let newItem = await retrieveNewItem()
itemsRef.value.append(newItem)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Detailed Design&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ref와 mutableRef&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;extension Optional where Wrapped: ~Copyable &amp;amp; ~Escapable {
  /// optional 안에 payload가 있으면 그에 대한 borrow된 참조를 반환합니다.
  public var ref: Ref? {
    @lifetime(borrow self)
    get
  }
}

extension Optional where Wrapped: ~Copyable {
  /// optional 안에 payload가 있으면 그에 대한 mutable 참조를 반환합니다.
  public var mutableRef: MutableRef? {
    @lifetime(&amp;amp;self)
    mutating get
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개념적으로 &lt;b&gt;이 프로퍼티들은 optional과 그 payload의 소유권을 옮기는 역할을 해요. &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;ref&lt;/code&gt;를 호출하려면 최소한 &lt;code&gt;borrowing Optional&amp;lt;T&amp;gt;&lt;/code&gt;, 즉 &lt;code&gt;Ref&amp;lt;Optional&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;가 있어야 하는데, 이 &lt;code&gt;ref&lt;/code&gt;는 그 &lt;code&gt;Ref&amp;lt;Optional&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;를 받아 &lt;code&gt;Optional&amp;lt;Ref&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;로 만들어줍니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;참조를 optional 내부로 옮겨서, 우리가 mutate하거나 consume하거나 독점적으로 접근할 수 있는 owned 값을 돌려받는 셈이죠. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;mutableRef&lt;/code&gt;도 마찬가지로 최소 &lt;code&gt;inout Optional&amp;lt;T&amp;gt;&lt;/code&gt;를 받아 owned &lt;code&gt;Optional&amp;lt;MutableRef&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; 값으로 바꿔줍니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;put()&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;extension Optional where Wrapped: ~Copyable {
  /// optional의 값을 새 값으로 설정하면서, optional 안에 새로 들어간
  /// payload에 대한 mutable 참조를 반환합니다.
  ///
  /// 이미 값이 있었다면 그 값은 destroy됩니다.
  @lifetime(&amp;amp;self)
  public mutating func put(_ new: consuming Wrapped) -&amp;gt; MutableRef
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;unsafelyUnwrapped 일반화&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;extension Optional where Wrapped: ~Copyable &amp;amp; ~Escapable {
  public var unsafelyUnwrapped: Wrapped {
    consuming get
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;map(), flatMap() 일반화&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;extension Optional where Wrapped: ~Copyable &amp;amp; ~Escapable {
  @lifetime(copy self)
  public consuming func map(
    _ transform: (consuming Wrapped) throws(E) -&amp;gt; Result
  ) throws(E) -&amp;gt; Result?

  @lifetime(copy self)
  public consuming func flatMap(
    _ transform: (consuming Wrapped) throws(E) -&amp;gt; Result?
  ) throws(E) -&amp;gt; Result?
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사실 &lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0437-noncopyable-stdlib-primitives.md#enum-optional&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SE-0437&lt;/a&gt; 당시에는 이 일반화를 급하게 적용 하고 싶지 않았다고해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;noncopyable 값을 다루는 &lt;code&gt;map&lt;/code&gt; / &lt;code&gt;flatMap&lt;/code&gt;에는 사실 세 가지 형태가 있을 수 있거든요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;optional 전체를 consume해서 owned 값을 클로저에 넘기거나, borrow해서 참조를 넘기거나, mutate해서 &lt;code&gt;inout&lt;/code&gt; 참조를 넘기거나. 셋 다 유용하지만, 전부 &lt;code&gt;map&lt;/code&gt;이라는 이름으로 오버로드하기엔 규칙상 구분할 방법이 없었죠. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 이번 제안은 &lt;b&gt;이 일반화를 기본적으로 항상 consuming으로 동작하게 만들고, 대신 &lt;code&gt;ref()&lt;/code&gt; / &lt;code&gt;mutableRef()&lt;/code&gt;로 owned optional 값을 먼저 만들어서 나머지 두 형태를 구현&lt;/b&gt;할 수 있게 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;func foo(x: consuming Optional&amp;lt;UniqueArray&amp;gt;) -&amp;gt; Optional {
  x.map {
    $0[0]
  }
}

func bar(x: borrowing Optional&amp;lt;Atomic&amp;gt;) -&amp;gt; Optional {
  x.ref.map { // ok!
    $0.value.load(ordering: .relaxed) &amp;amp;+ 1
  }
}

func baz(x: inout Optional&amp;lt;UniqueArray&amp;gt;) -&amp;gt; Optional {
  x.mutableRef.map {
    // map 하면서 array를 그 자리에서 업데이트
    $0.value.append(123)
    return $0.value.count
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Source Compatibility&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;Optional.ref&lt;/code&gt;, &lt;code&gt;Optional.mutableRef&lt;/code&gt;, &lt;code&gt;Optional.put()&lt;/code&gt;은 새로 추가되는 메서드라 소스 호환성 문제가 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;map&lt;/code&gt; / &lt;code&gt;flatMap&lt;/code&gt;의 새 오버로드는 기존 함수보다 덜 특수화된 오버로드예요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존에 &lt;code&gt;Optional.map&lt;/code&gt;을 쓰던 코드는 모두 &lt;code&gt;Copyable&lt;/code&gt; wrapped 값을 다루고 있었을 테니, 더 특수화된 기존 &lt;code&gt;Wrapped: Copyable&lt;/code&gt; 오버로드로 그대로 resolve됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; &lt;code&gt;flatMap&lt;/code&gt;도 마찬가지고요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 이 일반화된 함수들로 인한 소스 호환성 문제는 없을 것으로 예상합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;unsafelyUnwrapped&lt;/code&gt;는 순수한 일반화라 소스 호환성 문제를 일으키지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ABI Compatibility&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;Optional&lt;/code&gt;에 추가되는 새 메서드들은 표준 라이브러리의 새 API지만 별도 ABI를 필요로 하지 않아요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;map&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;unsafelyUnwrapped&lt;/code&gt;의 일반화 역시 새로운 ABI를 추가하거나 기존 ABI를 깨뜨리지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Implications on Adoption&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;Optional.ref&lt;/code&gt;, &lt;code&gt;Optional.mutableRef&lt;/code&gt;, &lt;code&gt;Optional.put()&lt;/code&gt;은 &lt;code&gt;Ref&lt;/code&gt;와 &lt;code&gt;MutableRef&lt;/code&gt;와 동일한 availability를 가집니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나머지 일반화 부분들은 항상 사용 가능한 것으로 표시됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Future Directions&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Borrow와 inout 바인딩&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;앞으로 borrow/inout 바인딩을 지원하기로 한다면, 컴파일러가 optional에 대해 &lt;code&gt;if borrow&lt;/code&gt; / &lt;code&gt;if inout&lt;/code&gt; 패턴을 인식해서 조건부로 scope된 접근을 제공하게 할 수도 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;if borrow x = optional {
  
}

foo(optional) // ok&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;만약 이 방향이 &lt;code&gt;ref&lt;/code&gt; / &lt;code&gt;mutableRef&lt;/code&gt; 방식보다 낫다고 판단되면, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;unsafelyUnwrapped&lt;/code&gt;를 일반화하는 방식도 다시 고민해야 해요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;더 이상 항상 consuming일 수 없으니까요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;consumingMap&lt;/code&gt;, &lt;code&gt;borrowingMap&lt;/code&gt;, &lt;code&gt;mutatingMap&lt;/code&gt; 등을 따로 만드는 방법도 있지만, API가 계속 늘어나는 건 그리 썩 괜찮은 해법은 아니라고 하네요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Optional: Equatable / Hashable 일반화&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;SE-0499가 &lt;code&gt;Equatable&lt;/code&gt;, &lt;code&gt;Hashable&lt;/code&gt; 같은 프로토콜을 noncopyable / nonescapable conformer까지 지원하도록 일반화한 만큼, &lt;code&gt;Optional&lt;/code&gt;의 이 conformance들도 suppressed wrapped 타입을 지원하도록 일반화하는 게 당연해 보입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다만 특정 conformance가 어느 시점에 일반화됐는지 표현할 방법이 없어서, 오래된 ABI 안정 OS에서 실수로 제네릭 &lt;code&gt;==&lt;/code&gt;나 &lt;code&gt;hash(into:)&lt;/code&gt;를 호출해 payload를 copy해버리는 상황은 막아야 해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Ref / MutableRef 자동 역참조&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;제안된 예시들에서 &lt;code&gt;ref&lt;/code&gt; / &lt;code&gt;mutableRef&lt;/code&gt;로 &lt;code&gt;map&lt;/code&gt;을 쓸 때 &lt;code&gt;.value&lt;/code&gt; 프로퍼티를 명시적으로 접근해야 했죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 앞으로 &lt;code&gt;Ref&lt;/code&gt;와 &lt;code&gt;MutableRef&lt;/code&gt;에 자동 역참조 기능을 추가해서, 아래처럼 더 편하게 쓸 수 있게 할 수도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; overflow: auto;&quot;&gt;&lt;code&gt;func bar(x: borrowing Optional&amp;lt;Atomic&amp;gt;) -&amp;gt; Optional {
  x.ref.map { // ok!
    // '.value.'가 더 이상 필요 없음
    $0.load(ordering: .relaxed) &amp;amp;+ 1
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Alternatives Considered&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Optional 바인딩의 기본 소유권 방식 변경&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 제안의 동기에서는 &lt;code&gt;ref&lt;/code&gt;, &lt;code&gt;mutableRef&lt;/code&gt; 같은 프로퍼티가 borrowing 버전의 제어 흐름을 위해 필요하다고 설명했어요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;대신 &lt;code&gt;if let&lt;/code&gt; 같은 optional 바인딩의 기본 소유권 방식을 borrowing으로 바꾸는 방법도 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 이건 optional 바인딩이 consuming이라고 가정하는 기존 코드에 대해 source-breaking 변경이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Optional.borrow()와 Optional.mutate() 메서드&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이전 리비전에서는 &lt;code&gt;ref&lt;/code&gt;, &lt;code&gt;mutableRef&lt;/code&gt; 대신 &lt;code&gt;borrow()&lt;/code&gt;, &lt;code&gt;mutate()&lt;/code&gt;라는 메서드 이름을 제안했었어요. 하지만 &lt;code&gt;InlineArray&lt;/code&gt;나 &lt;code&gt;UniqueArray&lt;/code&gt; 같은 타입의 &lt;code&gt;span&lt;/code&gt;, &lt;code&gt;mutableSpan&lt;/code&gt; 프로퍼티와 결을 맞추고 싶어서 최종적으로는 프로퍼티 형태가 더 선호됐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;noncopyable optional을 다루는 게 이번 제안으로 한결 편해질 것 같아요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;지금까지는 내부 값을 살짝 들여다보기만 해도 consume 에러를 피하려고 switch 문을 직접 작성해야 했는데, &lt;code&gt;ref&lt;/code&gt; / &lt;code&gt;mutableRef&lt;/code&gt; 덕분에 &lt;code&gt;if let&lt;/code&gt;처럼 자연스럽게 접근할 수 있게 됐습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;put()&lt;/code&gt;도 강제 언래핑을 줄여주는 실용적인 추가고요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;map&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;unsafelyUnwrapped&lt;/code&gt;까지 일반화되면서, noncopyable 타입을 다루는 코드가 Copyable 타입을 다룰 때와 비슷한 느낌으로 작성할 수 있을 것 같습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;border-left: 4px solid #3a8c28; padding-left: 12px; margin-top: 32px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;References&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1784377874630&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;swift-evolution/proposals/0532-optional-noncopyable-improvements.md at main &amp;middot; swiftlang/swift-evolution&quot; data-og-description=&quot;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0532-optional-noncopyable-improvements.md&quot; data-og-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0532-optional-noncopyable-improvements.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QejmU/dJMb9c9KuFW/Zuc9qRuObCGBRVnm80VTe0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bssUwH/dJMb8Z3Eglv/iRJuxZnP2VNw5CbC9PJJGk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0532-optional-noncopyable-improvements.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0532-optional-noncopyable-improvements.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QejmU/dJMb9c9KuFW/Zuc9qRuObCGBRVnm80VTe0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bssUwH/dJMb8Z3Eglv/iRJuxZnP2VNw5CbC9PJJGk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;swift-evolution/proposals/0532-optional-noncopyable-improvements.md at main &amp;middot; swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Swift</category>
      <category>noncopyable</category>
      <category>SE-0532</category>
      <category>SWIFT</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/629</guid>
      <comments>https://green1229.tistory.com/629#entry629comment</comments>
      <pubDate>Sat, 18 Jul 2026 21:33:05 +0900</pubDate>
    </item>
    <item>
      <title>What's new in SwiftData (feat. WWDC 2026)</title>
      <link>https://green1229.tistory.com/628</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 포스팅에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;WWDC 2026에서 나온 SwiftData 부분에서 업데이트 사항들에 대해 살펴보고 정리&lt;/b&gt;&lt;/span&gt;해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Sectioning your fetches&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;먼저 SwiftData에서 섹션별로 데이터를 가져오는 방법을 보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.14.41.png&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhimzf/dJMcacX6ugh/K04KMnaVySXZgzEKWjOKP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhimzf/dJMcacX6ugh/K04KMnaVySXZgzEKWjOKP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhimzf/dJMcacX6ugh/K04KMnaVySXZgzEKWjOKP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhimzf%2FdJMcacX6ugh%2FK04KMnaVySXZgzEKWjOKP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;827&quot; height=&quot;428&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.14.41.png&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;428&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제는 이렇게 쿼리에서 옵션을 주어 그룹별로 묶을 수 있어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;각 섹션에선 ID 속성이 있고 이걸 활용하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Using custom types&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;모델에 커스텀 타입을 저장하는 기능 향상을 살펴볼께요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;SwiftData는 로드될 때 모델에 대한 스키마를 자동으로 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;스키마는 모델 클래스와 엔티티간 매핑을 정의하죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;대부분의 타입에선 이게 자동으로 작동해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그렇지만 모델 매크로로 어노테이션 되지 않은 클래스는 자동으로 검사할 수 없기에 SwiftData는 스키마 생성에 실패합니다  &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;만약 그렇다고 구현체에 접근할 수 없을 수 있잖아요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.18.23.png&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ttsoG/dJMcafAxHil/BOSilGDEXAsPPEHw16zjek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ttsoG/dJMcafAxHil/BOSilGDEXAsPPEHw16zjek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ttsoG/dJMcafAxHil/BOSilGDEXAsPPEHw16zjek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FttsoG%2FdJMcafAxHil%2FBOSilGDEXAsPPEHw16zjek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;643&quot; height=&quot;389&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.18.23.png&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그런 경우 이렇게 어트리뷰트 codable을 사용하여 주면 해결됩니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 속성은 SwiftData에 타입의 인코딩된 표현을 저장하도록 알려주는 역할을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;타입에 대한 스키마를 추론하는 대신에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;다만 염두해둬야할게 있는데, codable 속성의 내용은 SwiftData에 불투명합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이는 Predicate에서 결과를 필터링하는데 사용할 수 없음을 나타내요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;또는 정렬도 사용할 수 없어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;또한 codable 형태가 변경되면 속성을 추가하거나 제거하는 경우 마이그레이션이 트리거되지 않아요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 점을 주의해야 합니다!&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Codable 속성 사용은 SwiftData가 기본적으로 지원하지 않는 타입을 저장하는 탈출구라고 생각하면 좋습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;직접 정의했다면 왠만해선 Codable 사용을 금해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Observing data stores&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;스토어를 모니터링하고 데이터 변경 시 알림 받는 방법을 살펴볼께요.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.22.41.png&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTvIGj/dJMcaalCTfH/lzBtKCSoBE76r8uRfKaVIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTvIGj/dJMcaalCTfH/lzBtKCSoBE76r8uRfKaVIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTvIGj/dJMcaalCTfH/lzBtKCSoBE76r8uRfKaVIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTvIGj%2FdJMcaalCTfH%2FlzBtKCSoBE76r8uRfKaVIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;347&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.22.41.png&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;SwiftUI에서는 이렇게 데이터가 변경되면 뷰가 쿼리의 새로운 결과를 반영해 다시 렌더링합니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;만약 SwiftUI가 아닌 부분은 어떨까요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이걸 위해 이번 2027 릴리즈에선 ResultsObserver를 도입했습니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.24.50.png&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BkiZg/dJMb991pUis/lOGVAUVqMUgQPB8k33gHz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BkiZg/dJMb991pUis/lOGVAUVqMUgQPB8k33gHz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BkiZg/dJMb991pUis/lOGVAUVqMUgQPB8k33gHz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBkiZg%2FdJMb991pUis%2FlOGVAUVqMUgQPB8k33gHz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;335&quot; height=&quot;338&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.24.50.png&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;SwiftUI 쿼리처럼 데이터 가져오고 관찰하고 반영시키는 Swift Observation을 사용해요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.25.59.png&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2yfnH/dJMcaiKJjnj/mkFHPOGWflAZKsNGSfDMK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2yfnH/dJMcaiKJjnj/mkFHPOGWflAZKsNGSfDMK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2yfnH/dJMcaiKJjnj/mkFHPOGWflAZKsNGSfDMK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2yfnH%2FdJMcaiKJjnj%2FmkFHPOGWflAZKsNGSfDMK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;346&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.25.59.png&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이런식으로 사용될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;withContinuousObservation은 ObservationTracking 토큰을 반환&lt;/b&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 &lt;b&gt;토큰이 관찰의 수명을 정의&lt;/b&gt;하죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;여기서 더 나아가 이번 업데이트에서는 히스토리 관찰도 지원해줍니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.30.26.png&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfHSrK/dJMcahymdti/kXjRP0UithYrkaAwFRRAsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfHSrK/dJMcahymdti/kXjRP0UithYrkaAwFRRAsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfHSrK/dJMcahymdti/kXjRP0UithYrkaAwFRRAsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfHSrK%2FdJMcahymdti%2FkXjRP0UithYrkaAwFRRAsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;394&quot; height=&quot;305&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.30.26.png&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;데이터 스토어가 저장될 때마다 SwiftData는 히스토리 트랜잭션을 기록합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;여기에는 변경된 내용에 대한 정보가 포함됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그리고 변경이 어디서 왔는지 조차도 포함되죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;히스토리에서 트랜잭션을 고유하게 식별하는 토큰도 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ModelContext.fetchHistory() 이 API와 토큰을 함께 사용할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.32.27.png&quot; data-origin-width=&quot;887&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XR4c2/dJMcagzpXq5/HWOKwsRkZ6kpSXKFhfVf6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XR4c2/dJMcagzpXq5/HWOKwsRkZ6kpSXKFhfVf6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XR4c2/dJMcagzpXq5/HWOKwsRkZ6kpSXKFhfVf6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXR4c2%2FdJMcagzpXq5%2FHWOKwsRkZ6kpSXKFhfVf6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;887&quot; height=&quot;282&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.32.27.png&quot; data-origin-width=&quot;887&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;HistoryObserver는 스토어의 변경 사항에 쉽게 반응할 수 있게 해줍니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지속적 히스토리 관찰과 새로운 트랜잭션 추가 시 코드가 반응하도록 해주죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;특정 종류의 변경만 관찰하고 대응하고 싶다면 물론 HistoryObserver를 사용해 모델 타입과 트랜잭션 작성자로 필터링할 수 있어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;외부 서버와 같은 다른 시스템과 연동 시 효과적이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;외부와 연동하는 예시를 볼까요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.33.27.png&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UNBRA/dJMcacX6usv/iFX1WrACfWzECbaNqu62Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UNBRA/dJMcacX6usv/iFX1WrACfWzECbaNqu62Gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UNBRA/dJMcacX6usv/iFX1WrACfWzECbaNqu62Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUNBRA%2FdJMcacX6usv%2FiFX1WrACfWzECbaNqu62Gk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;833&quot; height=&quot;425&quot; data-filename=&quot;스크린샷 2026-07-12 오후 6.33.27.png&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 간단히 코드로 나타내서 사용할 수 있습니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1783848834990&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SwiftData의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&quot; data-og-description=&quot;SwiftData의 최신 개선 사항을 확인하세요. Codable을 사용하여 맞춤형 및 타사 유형을 유지하는 방법과 가져온 데이터를 SwiftUI 앱의 섹션으로 그룹화하는 방법을 안내합니다. 또한 ModelResultsObserver와&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/274/&quot; data-og-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/274/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c55bAO/dJMb8RR33zg/erWRND5znnmRHJeEdxsxaK/img.jpg?width=500&amp;amp;height=282&amp;amp;face=0_0_500_282,https://scrap.kakaocdn.net/dn/HJkIe/dJMb8WeLUTG/t1q0uDdC6kJJcb5kKQPkh0/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=0_0_1800_1012&quot;&gt;&lt;a href=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/274/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/274/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c55bAO/dJMb8RR33zg/erWRND5znnmRHJeEdxsxaK/img.jpg?width=500&amp;amp;height=282&amp;amp;face=0_0_500_282,https://scrap.kakaocdn.net/dn/HJkIe/dJMb8WeLUTG/t1q0uDdC6kJJcb5kKQPkh0/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=0_0_1800_1012');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SwiftData의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SwiftData의 최신 개선 사항을 확인하세요. Codable을 사용하여 맞춤형 및 타사 유형을 유지하는 방법과 가져온 데이터를 SwiftUI 앱의 섹션으로 그룹화하는 방법을 안내합니다. 또한 ModelResultsObserver와&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>SwiftData</category>
      <category>ios</category>
      <category>SWIFT</category>
      <category>SwiftData</category>
      <category>WWDC 2026</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/628</guid>
      <comments>https://green1229.tistory.com/628#entry628comment</comments>
      <pubDate>Sun, 12 Jul 2026 18:36:37 +0900</pubDate>
    </item>
    <item>
      <title>느즈막히 올려보는 쿠팡에서의 회고 (feat. 또다른 시작)</title>
      <link>https://green1229.tistory.com/627</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이번 포스팅에서는 &lt;b&gt;사실 기술적인 부분보다 회고를&lt;/b&gt; 하나 해볼까 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제가 근 1년 6개월 정도 근무했던 쿠팡을 떠나게 되었는데, 사실 쿠팡 입사 직후와 3개월쯤 되었을때 각각 쿠팡 이직기라던지 쿠팡에서의 일상 회고를 해보려 했는데, 일과 개인적인 바쁨에 치여 결국 쿠팡을 나올때 이렇게 회고를 올려보네요  &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서, 이번 회고는 역시나 무근본 무형식으로 그냥 두서없이 한번 적어보려고 합니다  &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;1448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W5hQx/dJMcacwYj5X/JYRjfnXGirwek85iJeDvE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W5hQx/dJMcacwYj5X/JYRjfnXGirwek85iJeDvE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W5hQx/dJMcacwYj5X/JYRjfnXGirwek85iJeDvE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW5hQx%2FdJMcacwYj5X%2FJYRjfnXGirwek85iJeDvE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;440&quot; height=&quot;598&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;1448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쿠팡 입사&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;25년 2월에 쿠팡으로 이직을 하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;왜 이직했는지 그냥 지금와서 간단히 정리해보면, 정말 글로벌 서비스를 하는것과 글로벌 회사에서 일하는것을 경험해보고 싶었어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이전까지는 iOS 개발자 1인으로 내 할일을 다하는것에 초점이였다면 앞으로의 성장을 생각했을때 그걸 넘어서 정말 일을 잘하는 사람이 되고 싶었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발에 국한된게 아니라 일을 잘하는 사람이요.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그랬을때 좀 더 큰 대규모의 서비스를 경험해보면서 다국가 인종과 일하는 경험 이 두가지가 쿠팡을 지원하고 입사를 하게된 가장 큰 이유였습니다  &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서 쿠팡에서 쿠팡이츠라는 O2O 배달 앱 서비스의 시니어 iOS 엔지니어로 근무를 하게 됩니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그럼 쿠팡에서의 1년 6개월을 돌이켜봤을때 어떤것을 해왔고 어떤걸 배웠는지 한번 정리해볼까해요.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Life in Coupang&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우선 일은 굉장히 굉장히 하드워킹이긴 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그렇다고 밤낮이 없는 삶, 원양어선 그런건 아니였어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그냥 주어진 시간에 정말 1초도 쉬지 않고 일하면 다 끝날 수 있는 그런 정도..?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제가 맡은 TF는 주로 Ads TF였습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;배달 앱의 특성 상 배달이나 플랫폼 수수료 같은걸로는 정부 규제도 있고 단가가 그렇게 크지 않아 사실상 사업적인 부분에서 큰 이익이 되지 않는다고 생각해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그렇기에 또 다른 비지니스적인 부분을 고려할때 광고를 무시할 수 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;점포나 메뉴 광고가 주인데 어떤 부분에 배치하거나 어떤 시간대에 어떤걸 배치하면 이 점포를 가장 극대화되어서 CPC나 CPS를 올릴 수 있을지 같이 고민하고 여러 실험을 해보는 그런 TF입니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;광고라는 도메인이 익숙치도 않고 처음 해보는거였지만 그만큼 재밌었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;직접적으로 주간으로 광고를 통해 얼마나 많은 매출에 기여했는지 확연하게 눈에 보일 수 있었기에 더 동기부여가 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한, 광고 TF말고도 두루 경험해봤던것도 큰 기억으로 남아요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;핵심인 음식 배달과 요즘 밀고 있는 쇼핑(마트나 편의점, 꽃집 등등 - 푸드가 아닌 모든것) 그리고 고객들의 VOC나 편의성을 개선하기 위한 CRM TF 등 한 팀에 정말 다양한 TF가 로테이션으로 돌아가며 일을 하게 되는데 이 모든것의 비지니스 태스크를 한번씩은 해본것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러다보니 자연스레 다양한 코드들을 보게되고 깊게 이해하게 되었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-size=&quot;size18&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 거시적으로 볼 수 있는 비지니스적인 일은 어떻게 했는지에 대해 간단히 회고를 해본다면 이제는 팀에 대한 회고를 해볼까해요.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사실상 가장 많이 짧다면 짧은 시간에 성장할 수 있게 된 원동력이 바로 소속된 iOS 팀이였습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;솔직하게 지금까지 나름 다양한 회사도 다녀보고 여러 동아리도 해보고 컨퍼런스도 다녀보면서 교류해봤지만 개발자 개개인의 역량으로는 쿠팡이 가장 월등하다고 느꼈어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쿠팡의 채용 과정이 정말 복잡하고 난이도가 큰 편이라 더 그런지는 몰라도 개발자의 능력은 어느 회사보다도 뛰어나다고 확신할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그렇기에 같이 부딪히며 토론하고 때론 설전도 벌이면서 일을 하면서 성장한것 같아요  &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쿠팡에서 일하기 전까지의 저를 돌이켜보면 iOS 개발 맡은거 능히 해낼 수 있는 개발자라고 말할 수 있다면, 여기서 배운건 그건 당연히 해야되는거고 그거 말고도 너가 더 뭘할 수 있는데?에 대한 푸시가 많고 그걸 잘 끌어올려줄 매니저와 팀원들이 존재했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;너가 1인분 하는건 당연히 시니어 개발자가 아니라 주니어 개발자여도 당연히 해야되는거고, 그걸 넘어서 시니어 개발자라면 팀에 어떤 영향을 미칠 수 있는지 고민하고 iOS 뿐만 아니라 더 스펙트럼을 넓혀서 안드로이드, 웹을 포함한 프론트 그리고 백엔드까지 비지니스 스펙을 받으면 고려해서 테크적인 리드를 할 줄 알아야 하며 그런 부분을 하드 트레이닝을 많이 했던것 같아요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 일감이 주어지면 항상 어떻게 개발해야하지? 라는 생각보다 이게 정말 괜찮은 실험인지 이 실험을 성공시키기 위해서 각 파트에서 어떤 노력을 기울이면 좋을지 그리고 그게 제일 효과적인 방법일지를 고민하게 저의 일을 접근하는 방식 자체가 많이 변화한것 같아요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그전에는 iOS 앱 개발 부분에서만 고민했다면 이제는 백엔드와의 트레이드오프도 생각해보고 좀 더 크로스 플랫폼에서 일하기 적절한 방법과 그리고 기능 개발 대비 어느정도 인력 코스트가 들어가는지 그런것들까지 고민하고 제안을 하게 되는 개발자로 성장했어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 그건 제가 원하지 않아도 쿠팡에서 일을 하면 자연스럽게 요구되는 역량이고 그렇게 변하게 만들어주더라구요  &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 팀적으로도 &lt;b&gt;매주 테크 미팅을 통해 서로 기술을 공유하고 새로 맡은 비지니스 일감이 있다면 항상 먼저 테크 디자인을 한 후 공유해서 더 나은 방향이 있는지를 모바일 팀 자체적으로 더 체크&lt;/b&gt;를 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 꼼꼼하고 다양한 의견을 듣다보면 자연스럽게 시야도 넓어지게 되더라구요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쿠팡에서는 이렇게 정말 많은 미팅과 룰과 일이 존재해요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러다보니 눈코 뜰 새가 없는건 사실이지만 어떻게 보면 가장 이상적인 시스템이라곤 생각이 되더라구요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 시스템에서 번아웃이 안오고 버티는게 힘든것 뿐이지만 회사적인 측면으로만 보면 합리적이고 비지니스가 성장할 수 있는 시스템이란 생각이 많이 듭니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 또 많이 성장했던 부분은 바로 영어일것 같아요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사실 영어를 잘하지 못했고 지금도 그렇지만 하나 달라진건 자신감인것 같아요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회사에선 공식적으로 한국어로 일하는것 자체가 없어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공용 언어가 영어이기에 슬랙, 위키 등등 모든것이 영어죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 미팅도 통역이 제공되는 경우도 있지만 기본이 영어입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러다보니 사실 살려면 해야됐었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저도 처음에 입사해서 &quot;아 이거 일보다 커뮤니케이션이 영어라 따라갈 수 있나?&quot; 싶었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 슬랙도 그렇고 번역기에 번역하고 하고 싶은 말도 번역해서 떠듬떠듬 치고 그랬죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데 이게 일상에 녹아드니 별다른 영어 공부를 하지 않아도 자연스럽게 익숙해지기 마련이더라구요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 전에는 예를 들어 &quot;이거 확인해주실 수 있나요?&quot; 라는걸 영어로 말해야된다 생각하면 머릿속에서 문법부터 생각하고 완성한 다음 이게 진짜 맞나 고민하고 그런것들때문에 영어가 입 밖으로 더 안나왔던것 같아요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데 이제는 일단 문법이 다 맞지 않고 그렇더라도 이 바쁜 일상에서 우선 커뮤니케이션이 우선이고 먼저 말해야된다는 압박이 있다보니 자연스레 &quot;Could you check this?&quot;와 같이 나오게 되더라구요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;물론 더 좋은 표현도 있고 하겠지만 배운 한가지가 자신감이라 했잖아요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 자신감은 확실히 익힌것 같아요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 말로 표현하고 문장으로 쓰는게 내가 틀렸다 하더라도 두렵지가 않게 되었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 앞서 계속 말했지만 팀원들 정말 훌륭하고 귀중한 팀원들 그리고 타 팀의 교류하는 사람들 모두 좋은 인프라를 쌓을 수 있어 감사했어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일이 빡센만큼 전우애가 더 많이 생기게 되는 쿠팡이였어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;나간다니 이런 것까지 해주는 팀원들인데 어떻게 잊을 수 있을까 싶어요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9900.JPG&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdbwwc/dJMcadbtC6A/PhGnBgVv7EdPn1DY5EqCVk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdbwwc/dJMcadbtC6A/PhGnBgVv7EdPn1DY5EqCVk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdbwwc/dJMcadbtC6A/PhGnBgVv7EdPn1DY5EqCVk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcdbwwc%2FdJMcadbtC6A%2FPhGnBgVv7EdPn1DY5EqCVk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;321&quot; height=&quot;570&quot; data-filename=&quot;IMG_9900.JPG&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서 정리해보면 쿠팡에서 생활하면서 성장한 부분은 이렇습니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1️⃣ 기술적인 견고함과 더 넓게 바라볼 수 있는 시야&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2️⃣ 개인 혼자만이 아니라 팀 전체에 영향을 미칠 수 있는 사고&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3️⃣ 영어 의사소통&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4️⃣ 정말 비지니스적으로 어떤것들이 도움되는지에 대한 고민&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 외에도 서버 드리븐적인 설계, 대쉬보드들을 구축해서 모니터링을 강화하는 방법, 장애 대응, AI 오너로써 팀을 이끌어본 경험 등등 기술적으로나 팀에 영향을 주는 부분으로나 정말 다양한 포인트들이 있지만 그거까지 쓰면 한도 끝도 없을것 같아 우선 쿠팡에서의 라이프는 간략하게 이정도로 마칠까 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그럼 가장 중요한 포인트인데 왜 쿠팡을 떠나는지에 대해 간단히 정리하고 마쳐보려고 해요.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Why am I leaving Coupang?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;당연히 이직이 쉬운 선택도 아니고 또 새로운 도전을 하는것은 더더욱 쉬운 선택이 아닙니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 그런 결정을 하기까지에는 정말 큰것부터 정말 사소한것까지 많은 복합적인 부분이 상호작용 할거에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기선 몇가지 핵심적인 이유를 전해볼까해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우선, 쿠팡이 다니기에 좋지 않은 회사다 라는것은 전혀 아닙니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일이 힘들 순 있지만 그거때문에 이직하는건 도피라고 생각해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어딜가나 힘든건 있기 마련이고 일이 바쁘다고 나가는건 근로자의 덕목이 아니라 생각하기 때문이죠.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1️⃣ 더 넓은 글로벌 서비스&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가장 큰것중 하나는 바로 이 항목이에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쿠팡이츠를 개발하면서 현재는 한국과 일본을 타겟으로 서비스하고 있는데, 일본을 고려해서 글로벌한 서비스를 구축하고 운영하다 보니 정말 더 많은 나라들 나아가서 대륙들을 타겟으로 하는 더 큰 글로벌 서비스들이 궁금해졌어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 글로벌 서비스를 해보니 재미가 있더라구요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;같은 앱이지만 각 문화 환경에 따라 원하는 화면과 폰트 배치들이 다르다는것도 세삼 느끼게 되면서 뭔가 리전을 바꿀때마다 여행하는 느낌이 들었어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;직간접적으로 그 나라를 체험해보는거죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 이를 충족하는 서비스를 해보고 싶다는 생각이 컸습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2️⃣ 컨텐츠 플랫폼에 대한 니즈&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 저는 사실 개발자를 처음 해올때부터 사용자들이 몰두할 수 있는 컨텐츠 플랫폼을 해보고 싶었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;지금까지는 주로 커머스, O2O와 같은 사용자들이 앱에 들어와서 빠르게 확인하고 구매하고 나가는 그런 동선으로 비지니스를 이끄는 서비스였어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러다보니 한 화면에서 애니메이션이나 더 심미적인 부분보다는 탐색 플로우나 결제 플로우에서 로직과 빠른 구매가 더 중요해지더라구요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 한편으로는 그런 부분들을 많이 다룰 수 없었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여담이지만 저는 KWDC 2023에서 SwiftUI 애니메이션 관련 세션을 발표할 정도로 심&lt;b&gt;미적인것과 사용자의 더 아름다운 경험을 구현하는걸 원하고 좋아하는 개발자&lt;/b&gt;에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 그런 부분을 채울 수 있는 컨텐츠 플랫폼 서비스를 꼭 해보고 싶었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그럼 왜 여태까지 그런거 안했냐? 라고 한다면 안한게 아니라 못했던거라고 할 수 있어요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사실 알려진 컨텐츠 플랫폼 앱이 몇개 되지도 않지만 제가 원한다고 내일부터 그 회사에 들어가서 해볼 수 있는건 아니잖아요..?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;무튼 그래서 컨텐츠 플랫폼을 향한 저의 개발자로서의 니즈가 이직의 큰 몫을 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3️⃣ 거리&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마지막으로 누군가한테 사소할 수도 있지만 저한테 큰 부분이였던건 회사와의 거리였어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사실 쿠팡에 입사한것도 처음엔 하이브리드로 재택이 존재했기에 공고나 계약도 그렇게 진행되었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 선릉까지 출퇴근하는게 매일이 아니니 부담스럽지 않고 현실적으로 가능했죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데 작년부터 풀출근으로 근무제도가 변경되면서 이는 적지 않은 부담으로 다가왔어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(물론 모든 쿠팡 부서가 그런건 아니고 근무제도는 조직장에 따라 모두 부바부입니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러다보니 출퇴근 하는데 드는 시간, 체력소모, 비용 그런것들까지 트레이드 오프 되는것을 생각해볼때 쿠팡이 큰 메리트가 되지 않는단 생각이 문득 들더라구요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 사소할 수 있지만 저한텐 어떻게 보면 심리적으로 가장 큰 부분이였어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이런 대표적인 이유 + 말하진 않았지만 더 많은 이유들이 상호작용하여 이직을 결심하게 되었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(혹시 말하지 않았지만 더 많인 이유들이 궁금하시다면 연락주세요 ㅋㅋㅋ)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서 이번엔 어딜 가는데?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이번에는 1과 2그리고 3번의 이직 이유들을 충족할 수 있는 곳으로 가게되었어요.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crY72j/dJMcadvLNul/U9CuFDvM4fKZeLkjCwtvKK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crY72j/dJMcadvLNul/U9CuFDvM4fKZeLkjCwtvKK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crY72j/dJMcadvLNul/U9CuFDvM4fKZeLkjCwtvKK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrY72j%2FdJMcadvLNul%2FU9CuFDvM4fKZeLkjCwtvKK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;291&quot; height=&quot;291&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네이버웹툰에서 글로벌 웹툰 iOS 앱 개발에 기여하게 되었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아직 출근전이고 이 글이 나가는 시점에서 한 주 후 첫출근을 하게 될 예정이라 떨리네요 ☺️&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;인터뷰들을 진행하며 제가 더 다른 성장하고 싶은 포인트와 해소하고 싶은 포인트들을 네이버 웹툰에서 더 다양하게 해볼 수 있을것 같아 많은 기대가 됩니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아 그리고 현재 쿠팡에서 해당 제 포지션의 채용이 열려있어요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;관심 있으시거나 궁금한 부분이 있으신 분은 언제든 편하게 연락주시면 제가 아는선에서 알려드리고 도와드릴께요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제가 장담하건데 꼭 다녀봐야할 회사라고 생각합니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1783315930824&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Sr Mobile Engineer (Eats iOS)&quot; data-og-description=&quot;쿠팡이츠(Coupang Eats)는 쿠팡의 음식 배달 서비스이자,대한민국에서 빠르게 성장하고 있는 배달 서비스입니다. 2019년 국내 배달 업계에 혜성처럼 등장한 쿠팡이츠는 2024년 &amp;lsquo;무제한 무료배달&amp;rsquo;로&quot; data-og-host=&quot;www.coupang.jobs&quot; data-og-source-url=&quot;https://www.coupang.jobs/kr/jobs/7991999/sr-mobile-engineer-eats-ios/?gh_jid=7991999&quot; data-og-url=&quot;https://www.coupang.jobs/kr/jobs/7991999/sr-mobile-engineer-eats-ios/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cyqOMW/dJMb8UH0H9e/RHjnMaYoA85KVEBn3iQ4CK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.coupang.jobs/kr/jobs/7991999/sr-mobile-engineer-eats-ios/?gh_jid=7991999&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.coupang.jobs/kr/jobs/7991999/sr-mobile-engineer-eats-ios/?gh_jid=7991999&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cyqOMW/dJMb8UH0H9e/RHjnMaYoA85KVEBn3iQ4CK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Sr Mobile Engineer (Eats iOS)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;쿠팡이츠(Coupang Eats)는 쿠팡의 음식 배달 서비스이자,대한민국에서 빠르게 성장하고 있는 배달 서비스입니다. 2019년 국내 배달 업계에 혜성처럼 등장한 쿠팡이츠는 2024년 &amp;lsquo;무제한 무료배달&amp;rsquo;로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.coupang.jobs&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;또 어떤 재밌는 일들이 벌어지고 경험하게 될지 모르겠지만, 언젠가 또 좋은 회고로 찾아오도록 하겠습니다  &lt;/span&gt;&lt;/blockquote&gt;</description>
      <category>회고</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/627</guid>
      <comments>https://green1229.tistory.com/627#entry627comment</comments>
      <pubDate>Mon, 6 Jul 2026 13:39:50 +0900</pubDate>
    </item>
    <item>
      <title>What's new in SwiftUI (feat. WWDC 2026)</title>
      <link>https://green1229.tistory.com/626</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이번 포스팅에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;WWDC 2026에서 소개된 What's new in SwiftUI 세션을 정리&lt;/b&gt;&lt;/span&gt;해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;뭔가 오랜만에 SwiftUI를 공부하고 정리하는것 같아 재밌을것 같아요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Refreshed look and feel&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;리퀴드 글래스 기능이 나온건 벌써 좀 되었지만, 여전히 강조하고 개선시키고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.04.12.png&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CQflN/dJMcajo7PHo/nt4t2B5oET8rQbjWx6q4y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CQflN/dJMcajo7PHo/nt4t2B5oET8rQbjWx6q4y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CQflN/dJMcajo7PHo/nt4t2B5oET8rQbjWx6q4y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCQflN%2FdJMcajo7PHo%2Fnt4t2B5oET8rQbjWx6q4y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;727&quot; height=&quot;338&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.04.12.png&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;appearsActive 환경값을 통해 창이 비활성화 일때 불투명도를 조절할 수 있어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;또한, 이제 macOS나 iPadOS에서 메뉴바가 정말 심플해졌는데요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;원한다면 labelStyle을 통해 타이틀과 아이콘이 같이 나오도록도 설정할 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.05.19.png&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U1DMK/dJMcabktX8a/JLDWrlIWehmokV3fxbwFYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U1DMK/dJMcabktX8a/JLDWrlIWehmokV3fxbwFYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U1DMK/dJMcabktX8a/JLDWrlIWehmokV3fxbwFYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU1DMK%2FdJMcabktX8a%2FJLDWrlIWehmokV3fxbwFYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;321&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.05.19.png&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그리고 어쩌면 폴더블을 예상케하는 기능도 생겨났어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;iOS 27에서는 프리뷰를 통해 앱이 대화형 크기 조정에 어떻게 반응하는지 볼 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이렇게 늘리고 줄여서 이상이 없는지 바로 확인할 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이는 추후 출시된다는 소문이 많은 폴더블에 대한 대응을 미리 해놔라 라는 의미로도 들려지네요  &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.06.42.png&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y39rD/dJMcajbBzeN/CEVQoDtqh7w0NHOGcJYK3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y39rD/dJMcajbBzeN/CEVQoDtqh7w0NHOGcJYK3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y39rD/dJMcajbBzeN/CEVQoDtqh7w0NHOGcJYK3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy39rD%2FdJMcajbBzeN%2FCEVQoDtqh7w0NHOGcJYK3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1430&quot; height=&quot;560&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.06.42.png&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 반응형은 SwiftUI로 앱을 구성하면 자동으로 따라오지만 만약 UIKit과 SwiftUI 모두 사용한다면 고려해야할 몇가지가 있습니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.09.31.png&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB9crk/dJMcaiRnU3h/jjUiJYBNuxkMTGfAUsgLx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB9crk/dJMcaiRnU3h/jjUiJYBNuxkMTGfAUsgLx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB9crk/dJMcaiRnU3h/jjUiJYBNuxkMTGfAUsgLx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB9crk%2FdJMcaiRnU3h%2FjjUiJYBNuxkMTGfAUsgLx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;445&quot; height=&quot;323&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.09.31.png&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;1️⃣ 스크린 지오메트리 확인&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;2️⃣ 디바이스 대신 사이즈 클래스 이용하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;3️⃣ 화면 회전과 같은 방향에 대해 체크&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이에 대해 더 자세히 알아보려면, 아래 세션을 참고하세요!&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1782695449888&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Modernize your UIKit app - WWDC26 - Videos - Apple Developer&quot; data-og-description=&quot;Discover the latest updates to UIKit. Learn how to update your iPhone app layouts to work great when resized with iPhone Mirroring and on...&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/videos/play/wwdc2026/278/&quot; data-og-url=&quot;https://developer.apple.com/videos/play/wwdc2026/278/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ftKZA/dJMb9b32t8M/tyrPDUQpmpJJeT2SSyZ961/img.jpg?width=500&amp;amp;height=282&amp;amp;face=219_37_264_86,https://scrap.kakaocdn.net/dn/Q7PTG/dJMb9cBSsTE/qUKXYgvoe2YZ0gBW1MPtIk/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=793_143_936_297&quot;&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2026/278/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/videos/play/wwdc2026/278/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ftKZA/dJMb9b32t8M/tyrPDUQpmpJJeT2SSyZ961/img.jpg?width=500&amp;amp;height=282&amp;amp;face=219_37_264_86,https://scrap.kakaocdn.net/dn/Q7PTG/dJMb9cBSsTE/qUKXYgvoe2YZ0gBW1MPtIk/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=793_143_936_297');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Modernize your UIKit app - WWDC26 - Videos - Apple Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Discover the latest updates to UIKit. Learn how to update your iPhone app layouts to work great when resized with iPhone Mirroring and on...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;탭뷰에서도 새로운 기능이 생겼습니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.11.47.png&quot; data-origin-width=&quot;2478&quot; data-origin-height=&quot;1260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cywT32/dJMcabrc06D/lyr1pzhhxD8PvUDXSDZeUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cywT32/dJMcabrc06D/lyr1pzhhxD8PvUDXSDZeUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cywT32/dJMcabrc06D/lyr1pzhhxD8PvUDXSDZeUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcywT32%2FdJMcabrc06D%2Flyr1pzhhxD8PvUDXSDZeUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2478&quot; height=&quot;1260&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.11.47.png&quot; data-origin-width=&quot;2478&quot; data-origin-height=&quot;1260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이렇게 우측에 특별한 탭 배치를 하고 싶다면 prominent role 속성을 주어 그걸 표현해낼 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이 탭 메뉴는 아래처럼 디바이스 사이즈에 따라 자동으로 크기가 변하거나, 항목의 갯수가 줄어들거나 늘어나게 표현될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.12.56.png&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BigG2/dJMcafmSjye/fn9buPo2NHnDQWiHK0uohk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BigG2/dJMcafmSjye/fn9buPo2NHnDQWiHK0uohk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BigG2/dJMcafmSjye/fn9buPo2NHnDQWiHK0uohk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBigG2%2FdJMcafmSjye%2Ffn9buPo2NHnDQWiHK0uohk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;743&quot; height=&quot;439&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.12.56.png&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이때 줄어들어서 숨겨진 메뉴들은 더보기 버튼을 통해 오버플로우 메뉴로 확인할 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.15.28.png&quot; data-origin-width=&quot;1586&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DTIeF/dJMcajo7PW7/s6bWGT4zZJc8Y1VvBWUOkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DTIeF/dJMcajo7PW7/s6bWGT4zZJc8Y1VvBWUOkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DTIeF/dJMcajo7PW7/s6bWGT4zZJc8Y1VvBWUOkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDTIeF%2FdJMcajo7PW7%2Fs6bWGT4zZJc8Y1VvBWUOkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1586&quot; height=&quot;476&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.15.28.png&quot; data-origin-width=&quot;1586&quot; data-origin-height=&quot;476&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;또한, 이렇게 ToolbarItemGroup에서 undo, redo가 기본적으로 숨겨져있는데 만약 가시성있게 주고 싶다면 visibilityPriority를 high로 속성을 지정해주면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;물론 이것도 이번 iOS 27에서 나온 기능이죠.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.17.12.png&quot; data-origin-width=&quot;1612&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pBOmT/dJMcaf78X31/sDjyYhapalrhKCCJL76dH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pBOmT/dJMcaf78X31/sDjyYhapalrhKCCJL76dH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pBOmT/dJMcaf78X31/sDjyYhapalrhKCCJL76dH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpBOmT%2FdJMcaf78X31%2FsDjyYhapalrhKCCJL76dH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1612&quot; height=&quot;530&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.17.12.png&quot; data-origin-width=&quot;1612&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;반대로, 오버플로우 메뉴로 숨기려면 ToolbarOverFlowMenu로 지정하면 됩니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.17.49.png&quot; data-origin-width=&quot;1590&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QAqLn/dJMcac4Gt28/k1diPt47TR8oG3Nrsud0ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QAqLn/dJMcac4Gt28/k1diPt47TR8oG3Nrsud0ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QAqLn/dJMcac4Gt28/k1diPt47TR8oG3Nrsud0ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQAqLn%2FdJMcac4Gt28%2Fk1diPt47TR8oG3Nrsud0ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1590&quot; height=&quot;508&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.17.49.png&quot; data-origin-width=&quot;1590&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;마지막으로, 절대 숨기지 않고 항상 표현해주고 싶은 메뉴가 있다면 이렇게 placement 속성에 tobBarPinned를 사용하면 되죠.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.19.24.png&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dC413I/dJMcadbogga/Mz9PbZzAOLeDiDMnoGX470/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dC413I/dJMcadbogga/Mz9PbZzAOLeDiDMnoGX470/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dC413I/dJMcadbogga/Mz9PbZzAOLeDiDMnoGX470/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdC413I%2FdJMcadbogga%2FMz9PbZzAOLeDiDMnoGX470%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1756&quot; height=&quot;484&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.19.24.png&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;컨텐츠가 많아서 스크롤 시 네비게이션 바를 숨기고 싶다면 toolbarMinimizeBehavior 뷰 모디파이어를 이제는 사용하여 원하는것을 구현할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Document-based apps&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;지금까지 &lt;b&gt;SwiftUI는 문서 기반 앱을 지원&lt;/b&gt;해왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이번 릴리즈에선 이걸 기반으로 더 확장된 새로운 API를 가져왔어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Document creation context&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.24.08.png&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/raQYd/dJMcacjhPMF/XUksstkvif5Ms6HNHvkHH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/raQYd/dJMcacjhPMF/XUksstkvif5Ms6HNHvkHH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/raQYd/dJMcacjhPMF/XUksstkvif5Ms6HNHvkHH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FraQYd%2FdJMcacjhPMF%2FXUksstkvif5Ms6HNHvkHH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;351&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.24.08.png&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이제 이렇게 &lt;b&gt;문서를 생성할때 빈 문서 혹은 사진으로 바로 문서를 만들 수 있어요.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이걸 가능하게 하는 코드들이 들어가서 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.25.21.png&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;804&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blHZSJ/dJMcaff6zaJ/lGYoUuNugpZ47kkxHKV1ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blHZSJ/dJMcaff6zaJ/lGYoUuNugpZ47kkxHKV1ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blHZSJ/dJMcaff6zaJ/lGYoUuNugpZ47kkxHKV1ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblHZSJ%2FdJMcaff6zaJ%2FlGYoUuNugpZ47kkxHKV1ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1370&quot; height=&quot;804&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.25.21.png&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;804&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이렇게 DocumentGroupLaunchScene에서 버튼을 두개 blank, photo로 구성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.25.28.png&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/McJhU/dJMcadoWstS/nEjtykFSfOKzts6Q69lwSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/McJhU/dJMcadoWstS/nEjtykFSfOKzts6Q69lwSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/McJhU/dJMcadoWstS/nEjtykFSfOKzts6Q69lwSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMcJhU%2FdJMcadoWstS%2FnEjtykFSfOKzts6Q69lwSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1434&quot; height=&quot;690&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.25.28.png&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그 후 DocumentGroup 구성으로 context를 넘겨주는것이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그러면 blank, photo 컨텍스트가 넘어가 만약 photo라면 자동으로 바로 사진 선택창을 띄우게 되는것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Performance&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;문서 기반 앱은 잦은 업데이트가 있고 또한 그에 따라 UI 업데이트도 잦을 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;성능은 어떻게 최적화 시켰을까요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.28.44.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B7XMw/dJMcaiRnVBy/ygXhodgcD2uZQnMqpRTWY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B7XMw/dJMcaiRnVBy/ygXhodgcD2uZQnMqpRTWY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B7XMw/dJMcaiRnVBy/ygXhodgcD2uZQnMqpRTWY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB7XMw%2FdJMcaiRnVBy%2FygXhodgcD2uZQnMqpRTWY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;176&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.28.44.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;우선은 가장 기본적으로 Obervable 매크로를 이용합니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이를 통해 업데이트 되어야 할 친구들만 업데이트 쳐서 성능을 어느정도 보장해주죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그치만, 가장 중요한건 읽기/쓰기 성능이죠.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.31.08.png&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwRa5N/dJMcafAnkFZ/xB9Co9EZfAuoICe3RcNWV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwRa5N/dJMcafAnkFZ/xB9Co9EZfAuoICe3RcNWV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwRa5N/dJMcafAnkFZ/xB9Co9EZfAuoICe3RcNWV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwRa5N%2FdJMcafAnkFZ%2FxB9Co9EZfAuoICe3RcNWV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1434&quot; height=&quot;634&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.31.08.png&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;634&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;여기서 새로운 API가 등장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;성능 향상을 위해 우선 WritableDocument 프로토콜을 채택합니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이는 세가지의 준수사항을 가지고 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;1️⃣ writableContentTypes: 문서의 타입을 나타냅니다. 여기서는 커스텀한 스티커문서 타입을 지정해줬어요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;2️⃣ snapshot: 쓰기 스냅샷을 지원해줍니다. 커스텀한 PageSnapshot 객체를 만들어 사용할 수 있죠.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;3️⃣ writer: DocumentWriter 프로토콜을 준수하며 지정된 형식으로 문서를 디스크에 쓰는 방법입니다. 요청된 컨텐츠 형식을 지정해요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DocumentWriter 프로토콜에는 snapshot의 개념이 존재합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.34.33.png&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xNrEp/dJMb99UqUjH/pXTW8O73RfvK2SbibokEeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xNrEp/dJMb99UqUjH/pXTW8O73RfvK2SbibokEeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xNrEp/dJMb99UqUjH/pXTW8O73RfvK2SbibokEeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxNrEp%2FdJMb99UqUjH%2FpXTW8O73RfvK2SbibokEeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1308&quot; height=&quot;622&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.34.33.png&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;여기서 준수할 사항은 write죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;write 메서드는 nonisolated이자 비동기입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;즉, 비용이 많이 드는 쓰기 작업 자체를 백그라운드에서 수행하게 하죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그리고, snapshot을 통해 업데이트가 필요한 부분만을 쓰죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이런 최적화에도 불구하고 당연히 쓰기 작업은 오래걸릴 수도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이때 progress인자로 주어지는 Subprogress API를 사용해 진행 사항을 알 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그 다음 ReadableDocument도 있어요.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.38.17.png&quot; data-origin-width=&quot;1750&quot; data-origin-height=&quot;934&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ldf5Z/dJMcaiRnV8R/ckO9ZJSWJCbmIFcaIfA1N1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ldf5Z/dJMcaiRnV8R/ckO9ZJSWJCbmIFcaIfA1N1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ldf5Z/dJMcaiRnV8R/ckO9ZJSWJCbmIFcaIfA1N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fldf5Z%2FdJMcaiRnV8R%2FckO9ZJSWJCbmIFcaIfA1N1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1750&quot; height=&quot;934&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.38.17.png&quot; data-origin-width=&quot;1750&quot; data-origin-height=&quot;934&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;둘은 쌍둥이라고 볼 수 있을 정도로 완벽하게 대칭됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;당연하겠죠?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 두가지를 활용하여 문서 읽기/쓰기 성능을 향상시켰습니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;First-class support for URL access&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;페이지를 이미지로 저장할 수도 있어야겠죠?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;앱이 없는 사람도 충분히 있으니까요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Document API writer를 활용하면 충분히 다른 형식으로도 저장이 가능합니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.40.28.png&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfy2hF/dJMcabSdQyK/TlIhYmMlWbuxgW4nvFKSX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfy2hF/dJMcabSdQyK/TlIhYmMlWbuxgW4nvFKSX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfy2hF/dJMcabSdQyK/TlIhYmMlWbuxgW4nvFKSX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcfy2hF%2FdJMcabSdQyK%2FTlIhYmMlWbuxgW4nvFKSX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1404&quot; height=&quot;260&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.40.28.png&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;우선,&lt;b&gt; writableContentTypes에 png도 넣어줍니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이미지로 저장을 위해서요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.41.08.png&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLtu5z/dJMcadoWsMM/nCPdKtNvy940lYgb3lvrn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLtu5z/dJMcadoWsMM/nCPdKtNvy940lYgb3lvrn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLtu5z/dJMcadoWsMM/nCPdKtNvy940lYgb3lvrn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLtu5z%2FdJMcadoWsMM%2FnCPdKtNvy940lYgb3lvrn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1298&quot; height=&quot;748&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.41.08.png&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그리고 Writer 구현체에서 contentType이 png일때 하나의 이미지로 합쳐지도록 코드를 추가해줘요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 해주면 손쉽게 이미지로 문서를 저장할 수 있습니다  &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Presentation and interaction&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;화면에 보이는 요소와 인터랙션에 대한 개선들이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.43.09.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIBs3C/dJMcacDHcmE/Wss5NQD5u082LdaaIADMvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIBs3C/dJMcacDHcmE/Wss5NQD5u082LdaaIADMvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIBs3C/dJMcacDHcmE/Wss5NQD5u082LdaaIADMvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIBs3C%2FdJMcacDHcmE%2FWss5NQD5u082LdaaIADMvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;996&quot; height=&quot;440&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.43.09.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;reorderable과 reorderContainer를 이용한다면 리스트에 있는 요소들의 순서를 내 마음대로 변경&lt;/b&gt;할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이 Reorderable API는 List만이 아니라 모든 컨테이너에서도 동일하게 적용하고 동작할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이제 SwiftUI는 List뿐만 아니라 모든 뷰에서 스와이프 동작을 지원합니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.48.03.png&quot; data-origin-width=&quot;1596&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs9FIR/dJMcaiw6pX5/kYNz5Aguoim1dV7UkajZB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs9FIR/dJMcaiw6pX5/kYNz5Aguoim1dV7UkajZB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs9FIR/dJMcaiw6pX5/kYNz5Aguoim1dV7UkajZB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs9FIR%2FdJMcaiw6pX5%2FkYNz5Aguoim1dV7UkajZB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1596&quot; height=&quot;554&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.48.03.png&quot; data-origin-width=&quot;1596&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;swipeActionsContatiner를 붙이고 그 안에서 아이템 섹션에는 원하는 swipeActions를 구성해주면 됩니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;또한 만약 항목을 제거하고싶다, 이 예시에서는 스티커를 제거하고 싶다? 라면 이렇게 할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.51.12.png&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0T83o/dJMcageX3su/FQE9S4ngqSAE5AyKrW85GK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0T83o/dJMcageX3su/FQE9S4ngqSAE5AyKrW85GK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0T83o/dJMcageX3su/FQE9S4ngqSAE5AyKrW85GK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0T83o%2FdJMcageX3su%2FFQE9S4ngqSAE5AyKrW85GK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1504&quot; height=&quot;792&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.51.12.png&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;우선 요렇게 contextMenu를 통해 삭제 버튼을 배치하고 stickerToDelete 변수에 저장되도록 해줍니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.52.04.png&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;912&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnZcIc/dJMcadvGqJy/LqO2798NSEpBOrEP3uuNnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnZcIc/dJMcadvGqJy/LqO2798NSEpBOrEP3uuNnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnZcIc/dJMcadvGqJy/LqO2798NSEpBOrEP3uuNnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnZcIc%2FdJMcadvGqJy%2FLqO2798NSEpBOrEP3uuNnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1510&quot; height=&quot;912&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.52.04.png&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;912&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그리고 이렇게 이번 API에서 업데이트된 confirmationDiaglog를 통해 삭제 다이얼로그를 구성하고 삭제나 다른 동작을 할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이건 alert 모디파이어로도 대체할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 밖에도 무수한 업데이트 사항들이 있어요ㅎㅎ&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Data flow and performance&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이제 데이터 흐름과 성능 주요 개선 사항들에 대해 살펴볼께요.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;잘 알고 있는, AsyncImage는 온라인의 이미지를 나타내는데 용이하고 나타날때 그려줬죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그리고, 지금까지는 이미지를 메모리에 유지하지 않았어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;즉, 캐싱이 없었죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그렇기에 다시 위로 스크롤하면 다시 그려줬습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이제 iOS 27부터는 AsyncImage가 표준 HTTP 캐싱을 지원해줍니다  &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;즉, 기본적으로 이미지 캐싱이 되는거죠!!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;별다른 코드 변경없이도 자동으로 적용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.57.43.png&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baw7t5/dJMcahLHUgt/OF7ycDLnKEkfSwu9m7Q1mK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baw7t5/dJMcahLHUgt/OF7ycDLnKEkfSwu9m7Q1mK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baw7t5/dJMcahLHUgt/OF7ycDLnKEkfSwu9m7Q1mK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbaw7t5%2FdJMcahLHUgt%2FOF7ycDLnKEkfSwu9m7Q1mK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;215&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.57.43.png&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;물론, cachePolicy 파라미터가 생겨 원하는 캐시 정책을 설정할 수도 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.58.40.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;828&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDDgvZ/dJMcac4GvBd/IjakI1UIg57HhEaTsc1Auk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDDgvZ/dJMcac4GvBd/IjakI1UIg57HhEaTsc1Auk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDDgvZ/dJMcac4GvBd/IjakI1UIg57HhEaTsc1Auk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDDgvZ%2FdJMcac4GvBd%2FIjakI1UIg57HhEaTsc1Auk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;540&quot; height=&quot;437&quot; data-filename=&quot;스크린샷 2026-06-29 오전 10.58.40.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;828&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;아니면, 이렇게 아예 커스텀한 캐시 정책을 추가할 수도 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;앱 데이터를 저장하는 좋은 방법은 Observable 클래스를 이용하는것이죠.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.00.18.png&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbgKRj/dJMcacKsNT5/XOfLRt7cuPAzImQ7JMqOE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbgKRj/dJMcacKsNT5/XOfLRt7cuPAzImQ7JMqOE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbgKRj/dJMcacKsNT5/XOfLRt7cuPAzImQ7JMqOE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbgKRj%2FdJMcacKsNT5%2FXOfLRt7cuPAzImQ7JMqOE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1456&quot; height=&quot;500&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.00.18.png&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이전까지는 &lt;b&gt;이 코드에서 만약 상위 뷰가 업데이트되어서 StickerStoreView가 초기화되면 StickerStore의 새 인스턴스가 만들어졌어요.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;하지만 원래 인스턴스가 여전히 State 변수에 저장되어 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그렇기에, 새 인스턴스는 그냥 버려졌죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이 기존 방식은 매번 초기화될때마다 새 인스턴스를 버리고 낭비하는 아주 안좋은 성능이였습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이제는 State 프로퍼티를 사용하여 초기화되고 저장되는 클래스가 lazy하게 되었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;즉, 한번만 초기화된다는 소리죠  &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이를 가능하게 하는건, @State Dynamic Property에서 @State Macro로 변환되었기에 가능합니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.03.38.png&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBN1D7/dJMcabdAKtn/o0kEkkZEN2TrnImqWpgPM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBN1D7/dJMcabdAKtn/o0kEkkZEN2TrnImqWpgPM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBN1D7/dJMcabdAKtn/o0kEkkZEN2TrnImqWpgPM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBN1D7%2FdJMcabdAKtn%2Fo0kEkkZEN2TrnImqWpgPM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;870&quot; height=&quot;160&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.03.38.png&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이제는 이후 초기화에서는 새 클래스 인스턴스를 만들지 않게 됩니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;더 좋은 소식은, 이 변환은 하위 호환도 백포팅 되어서 iOS 17도 적용이 자연스레 되었다는 점입니다!&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.06.02.png&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tjZhn/dJMcaftz03L/I2rZF5K6xRHYzXlDiweuQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tjZhn/dJMcaftz03L/I2rZF5K6xRHYzXlDiweuQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tjZhn/dJMcaftz03L/I2rZF5K6xRHYzXlDiweuQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtjZhn%2FdJMcaftz03L%2FI2rZF5K6xRHYzXlDiweuQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1472&quot; height=&quot;590&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.06.02.png&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;다만 이제는 이 변경으로 인해 이전 버전에서 이렇게 사용하고 있던 코드들이 초기화 관련 에러를 뱉을 수 있게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;즉, 선언 시 할당하지 않아야 합니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.09.07.png&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;498&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ml1ht/dJMcaaTmhBZ/c3hvLwSH4Z7tn9F4RP88a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ml1ht/dJMcaaTmhBZ/c3hvLwSH4Z7tn9F4RP88a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ml1ht/dJMcaaTmhBZ/c3hvLwSH4Z7tn9F4RP88a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fml1ht%2FdJMcaaTmhBZ%2Fc3hvLwSH4Z7tn9F4RP88a1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1706&quot; height=&quot;498&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.09.07.png&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그리고 어쩌면 가장 많이 개발자들을 괴롭히고 마주칠 수 있는 부분인데요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;뷰에 많은 중첩된 표현이 있다면 이렇게 컴파일러가 오류를 냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;즉, 주어진 해당 시간안에 컴파일러가 타입 체킹을 하기 어렵다는 투정이죠.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.11.53.png&quot; data-origin-width=&quot;1792&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6PT8r/dJMcaiw6rBp/4kAmz6P7ETSA0DlBzMBCvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6PT8r/dJMcaiw6rBp/4kAmz6P7ETSA0DlBzMBCvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6PT8r/dJMcaiw6rBp/4kAmz6P7ETSA0DlBzMBCvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6PT8r%2FdJMcaiw6rBp%2F4kAmz6P7ETSA0DlBzMBCvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1792&quot; height=&quot;716&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.11.53.png&quot; data-origin-width=&quot;1792&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이런일이 발생하는 &lt;b&gt;근본적인 원인은 컴파일러가 해당 컴포넌트를 그릴때 어떤 조건으로 그릴지 모르기에 다 시도해봐야되는거죠.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이렇게 선택지가 많고 중첩되면 더 복잡해질 수 밖에 없죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 복잡한걸 생성 유형에 제약을 받지 않고 컨텐츠를 그저 조합하기만 한다면 얼마나 좋을까요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이게 바로 이번 릴리즈에서 이룬것입니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.13.40.png&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;790&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUCiuF/dJMcaglH9bc/BlMN4l3ykBVG1CGSwN5fL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUCiuF/dJMcaglH9bc/BlMN4l3ykBVG1CGSwN5fL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUCiuF/dJMcaglH9bc/BlMN4l3ykBVG1CGSwN5fL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUCiuF%2FdJMcaglH9bc%2FBlMN4l3ykBVG1CGSwN5fL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;285&quot; height=&quot;569&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.13.40.png&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;790&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;가장 일반적인 빌더 집합이 이제 단일 이니셜라이저를 공유해 단 하나의 명확한 경로만 남깁니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.14.30.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cagujx/dJMcaiX4ZU0/H24972jGxVHBgYDzeQ9SAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cagujx/dJMcaiX4ZU0/H24972jGxVHBgYDzeQ9SAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cagujx/dJMcaiX4ZU0/H24972jGxVHBgYDzeQ9SAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcagujx%2FdJMcaiX4ZU0%2FH24972jGxVHBgYDzeQ9SAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;290&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.14.30.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;ContentBuilder가 나타났기에 가능한 일입니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;여러 다른 빌더 유형이 하나로 통합되었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;단일 빌더를 위해서요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이는 기존 ViewBuilder의 진화로 모든 타겟 버전에서 사용할 수 있습니다  &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그리고 이제는 AI 시대니까..&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이 명령어 한줄로 Swift나 SwiftUI 관한 애플의 스킬을 익스포트 받을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.19.06.png&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0ncIm/dJMcaaeMCki/tdSzcZlzutCCXmbqvMJeW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0ncIm/dJMcaaeMCki/tdSzcZlzutCCXmbqvMJeW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0ncIm/dJMcaaeMCki/tdSzcZlzutCCXmbqvMJeW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0ncIm%2FdJMcaaeMCki%2FtdSzcZlzutCCXmbqvMJeW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;168&quot; data-filename=&quot;스크린샷 2026-06-29 오전 11.19.06.png&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;개인적으로 엄청 많은 변화는 없다고 느껴지는데 알짜인 변화들이 있어 보여요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;AsyncImage도 이미지 캐싱이 되지 않아 쓰는 선택지에서 배제되었었는데 이제는 지원&lt;/b&gt;해준다니 감개무량하네요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;또한, &lt;b&gt;SwiftUI View 성능이 정말 항상 불만이였는데, 특히 컴파일러 뷰 타입 체크 성능 관련&lt;/b&gt;해서...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이것 또한 개선되었다니 큰 업데이트라고 생각됩니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이게 다 소개처럼 잘 작동하고 정말 체감이 되는거라면 Xcode 27로 업데이트 하지 않을 이유가 없네요ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1782699594963&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SwiftUI의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&quot; data-og-description=&quot;SwiftUI에 추가된 최신 기능을 살펴보고, 이러한 기능이 앱을 어떻게 향상할 수 있는지 알아보세요. 고성능 앱 빌드를 위한 직접 디스크 접근과 스냅샷 기반 비교 기능을 갖춘 새로운 Document 프로&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/269/&quot; data-og-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/269/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uBX4p/dJMb85vZCfE/pIKIn5JSYecFBsTll1ehSk/img.jpg?width=500&amp;amp;height=282&amp;amp;face=123_51_397_99,https://scrap.kakaocdn.net/dn/xUIbm/dJMb9eTZ0mr/Htj7lRpvtkJKSI9xGztYmk/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=447_182_1419_348&quot;&gt;&lt;a href=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/269/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/269/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uBX4p/dJMb85vZCfE/pIKIn5JSYecFBsTll1ehSk/img.jpg?width=500&amp;amp;height=282&amp;amp;face=123_51_397_99,https://scrap.kakaocdn.net/dn/xUIbm/dJMb9eTZ0mr/Htj7lRpvtkJKSI9xGztYmk/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=447_182_1419_348');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SwiftUI의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SwiftUI에 추가된 최신 기능을 살펴보고, 이러한 기능이 앱을 어떻게 향상할 수 있는지 알아보세요. 고성능 앱 빌드를 위한 직접 디스크 접근과 스냅샷 기반 비교 기능을 갖춘 새로운 Document 프로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>SwiftUI</category>
      <category>Apple</category>
      <category>ios</category>
      <category>swiftUI</category>
      <category>What's new in SwiftUI</category>
      <category>WWDC 2026</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/626</guid>
      <comments>https://green1229.tistory.com/626#entry626comment</comments>
      <pubDate>Mon, 29 Jun 2026 11:29:03 +0900</pubDate>
    </item>
    <item>
      <title>What's new in Swift (feat. WWDC 2026)</title>
      <link>https://green1229.tistory.com/625</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 포스팅에서는 얼마전 진행되었던 WWDC 2026에 대해 이제 하나씩 정리해보고자 합니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;첫번째 시작은 What's new in Swift에요.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;WWDC 2026에서 소개된 Swift 변화에 대한 핵심적인 것들을 세션을 보며 정리해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;특히 Swift 6.3과 Swift 6.4 기반에서 변화된 정리 내용이 주입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1782096052728&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Swift의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&quot; data-og-description=&quot;Swift 관련 업데이트를 확인해 보세요. 일상적인 인체공학, 향상된 동시성, 더 안전한 고성능 코드를 위한 업데이트 등 언어 관련 최신 혁신 기술을 알아보세요. Embedded Swift의 워크플로와 언어 상&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot; data-og-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kyB4C/dJMb87gf74E/PnnNbXmn7DY52TZS9kKRQk/img.jpg?width=500&amp;amp;height=282&amp;amp;face=0_0_500_282,https://scrap.kakaocdn.net/dn/gDaX7/dJMb8XSfvrL/9HOMkuuKFhUyKMYAzPlGc1/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=0_0_1800_1012&quot;&gt;&lt;a href=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kyB4C/dJMb87gf74E/PnnNbXmn7DY52TZS9kKRQk/img.jpg?width=500&amp;amp;height=282&amp;amp;face=0_0_500_282,https://scrap.kakaocdn.net/dn/gDaX7/dJMb8XSfvrL/9HOMkuuKFhUyKMYAzPlGc1/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=0_0_1800_1012');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Swift의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Swift 관련 업데이트를 확인해 보세요. 일상적인 인체공학, 향상된 동시성, 더 안전한 고성능 코드를 위한 업데이트 등 언어 관련 최신 혁신 기술을 알아보세요. Embedded Swift의 워크플로와 언어 상&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;우선 개선사항들부터 살펴볼까요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Improvements&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;옵셔널 타입&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.43.11.png&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eD2JtW/dJMcag60azq/icKDSYYXCVBpbDNBzY5H0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eD2JtW/dJMcag60azq/icKDSYYXCVBpbDNBzY5H0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eD2JtW/dJMcag60azq/icKDSYYXCVBpbDNBzY5H0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeD2JtW%2FdJMcag60azq%2FicKDSYYXCVBpbDNBzY5H0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;337&quot; height=&quot;296&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.43.11.png&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이전에는 some이나 any와 옵셔널을 같이 사용할때는 이렇게 괄호로 묶어야 됐어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이는 연산자 우선순위 규칙 관련해서 필수였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제는 아래와 같이 컴파일러가 똑디하게 판단해주기에 묶지 않아도 되게 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 6.4부터요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.44.28.png&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt5Eg5/dJMcag60aCj/ldwJ7OHPEYYsfB5rccp1Uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt5Eg5/dJMcag60aCj/ldwJ7OHPEYYsfB5rccp1Uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt5Eg5/dJMcag60aCj/ldwJ7OHPEYYsfB5rccp1Uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt5Eg5%2FdJMcag60aCj%2FldwJ7OHPEYYsfB5rccp1Uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;348&quot; height=&quot;302&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.44.28.png&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Concurrency&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.47.54.png&quot; data-origin-width=&quot;1758&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rpuWZ/dJMcaijs2Ul/RXSReAeFyk7hrkeUkMNdF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rpuWZ/dJMcaijs2Ul/RXSReAeFyk7hrkeUkMNdF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rpuWZ/dJMcaijs2Ul/RXSReAeFyk7hrkeUkMNdF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrpuWZ%2FdJMcaijs2Ul%2FRXSReAeFyk7hrkeUkMNdF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1758&quot; height=&quot;170&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.47.54.png&quot; data-origin-width=&quot;1758&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제 이 컨커런시 관련하여 오류를 무시하면 경고가 나타납니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.48.45.png&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gehbj/dJMcagTvgRW/4z4RLRLWRJnkoZYDJKHmi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gehbj/dJMcagTvgRW/4z4RLRLWRJnkoZYDJKHmi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gehbj/dJMcagTvgRW/4z4RLRLWRJnkoZYDJKHmi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGehbj%2FdJMcagTvgRW%2F4z4RLRLWRJnkoZYDJKHmi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;515&quot; height=&quot;380&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.48.45.png&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래서 이제는 이렇게 작업 내 오류를 처리하거나,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.49.32.png&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QpXE4/dJMcaf73TMZ/bJcvJ19kR0p7ufmUVRp451/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QpXE4/dJMcaf73TMZ/bJcvJ19kR0p7ufmUVRp451/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QpXE4/dJMcaf73TMZ/bJcvJ19kR0p7ufmUVRp451/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQpXE4%2FdJMcaf73TMZ%2FbJcvJ19kR0p7ufmUVRp451%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;204&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.49.32.png&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 작업을 저장해두었다가 나중에 처리하던가 해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.51.03.png&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUe132/dJMb991ajEG/3OkR6DFNs0sih0B4AAZgK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUe132/dJMb991ajEG/3OkR6DFNs0sih0B4AAZgK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUe132/dJMb991ajEG/3OkR6DFNs0sih0B4AAZgK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUe132%2FdJMb991ajEG%2F3OkR6DFNs0sih0B4AAZgK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;194&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.51.03.png&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;428&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제 defer block에서 async 함수를 호출하던 제한도 사라졌습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.51.59.png&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u7pHc/dJMcajbv6zJ/yAWKLrA5kAPjcrT7iptK5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u7pHc/dJMcajbv6zJ/yAWKLrA5kAPjcrT7iptK5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u7pHc/dJMcajbv6zJ/yAWKLrA5kAPjcrT7iptK5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu7pHc%2FdJMcajbv6zJ%2FyAWKLrA5kAPjcrT7iptK5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;552&quot; height=&quot;211&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.51.59.png&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;@Unchecked Sendable을 사용하던 클래스는 weak var 프로퍼티 때문이였을텐데요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제 weak let으로 설정한다면 @Unchecked를 붙이지 않아도 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그리고 만약 타입이 Sendable일 필요가 없다면, 새로운 tilde Sendable 구문으로 명시적으로 나타낼 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;서브 클래스가 Sendable이 되는것도 막지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.54.28.png&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIWXmL/dJMcahSloo4/7lmmK0yC5eHl9BuESVzzQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIWXmL/dJMcahSloo4/7lmmK0yC5eHl9BuESVzzQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIWXmL/dJMcahSloo4/7lmmK0yC5eHl9BuESVzzQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIWXmL%2FdJMcahSloo4%2F7lmmK0yC5eHl9BuESVzzQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;82&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.54.28.png&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Access level&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.55.21.png&quot; data-origin-width=&quot;1574&quot; data-origin-height=&quot;556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/quLmk/dJMcagzapVj/CADZu7tUTYQ1TS4kAtR5CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/quLmk/dJMcagzapVj/CADZu7tUTYQ1TS4kAtR5CK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/quLmk/dJMcagzapVj/CADZu7tUTYQ1TS4kAtR5CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FquLmk%2FdJMcagzapVj%2FCADZu7tUTYQ1TS4kAtR5CK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1574&quot; height=&quot;556&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.55.21.png&quot; data-origin-width=&quot;1574&quot; data-origin-height=&quot;556&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;internal과 private을 같는 등의 서로 다른 접근 레벨 프로퍼티를 가진 구조체는 이제 두번째 멤버와이즈 이니셜라이저를 가지게 되어 다른 프로젝트에서도 사용이 가능하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;anyAppleOS&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.57.25.png&quot; data-origin-width=&quot;1602&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxYeMw/dJMb997SSNj/QmBNKkjeqJB9Fc2S4BWYEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxYeMw/dJMb997SSNj/QmBNKkjeqJB9Fc2S4BWYEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxYeMw/dJMb997SSNj/QmBNKkjeqJB9Fc2S4BWYEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxYeMw%2FdJMb997SSNj%2FQmBNKkjeqJB9Fc2S4BWYEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;188&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.57.25.png&quot; data-origin-width=&quot;1602&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제 각 macOS, iOS 이렇게 다 나열할 필요없이 27 버전부터는 통일되었기에 이렇게 anyAppleOS로 통합해서 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;가용성을 한번에 통합해서 주기에 편리하죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.58.37.png&quot; data-origin-width=&quot;1678&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7iLK0/dJMcajo2IVa/saQNPGprXvzJwaf8j8WzKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7iLK0/dJMcajo2IVa/saQNPGprXvzJwaf8j8WzKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7iLK0/dJMcajo2IVa/saQNPGprXvzJwaf8j8WzKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7iLK0%2FdJMcajo2IVa%2FsaQNPGprXvzJwaf8j8WzKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;609&quot; height=&quot;80&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.58.37.png&quot; data-origin-width=&quot;1678&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;물론 이렇게 통합하고 하나를 예외로 두는 설정도 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;@diagnose&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.59.45.png&quot; data-origin-width=&quot;1656&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dyhgto/dJMcacXQI0O/SZKAhjTf0qqwVnjAKood80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dyhgto/dJMcacXQI0O/SZKAhjTf0qqwVnjAKood80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dyhgto/dJMcacXQI0O/SZKAhjTf0qqwVnjAKood80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdyhgto%2FdJMcacXQI0O%2FSZKAhjTf0qqwVnjAKood80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1656&quot; height=&quot;366&quot; data-filename=&quot;스크린샷 2026-06-22 오전 9.59.45.png&quot; data-origin-width=&quot;1656&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 디프리케이트된 API들은 경고가 뜨기 마련이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제는 이 경고를 나타나지 않게 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.00.28.png&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R1nIu/dJMcai4LxKS/a9ratFAPULLhtOhtfhdnKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R1nIu/dJMcai4LxKS/a9ratFAPULLhtOhtfhdnKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R1nIu/dJMcai4LxKS/a9ratFAPULLhtOhtfhdnKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR1nIu%2FdJMcai4LxKS%2Fa9ratFAPULLhtOhtfhdnKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;809&quot; height=&quot;192&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.00.28.png&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;요런식으로요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;다른 부분에선 영향을 주지 않고 해당 선언된 부분에서만 경고를 끌 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;추가로 인자로, StrictMemorySafety를 주어 보안이 중요한 메서드에서 unsafe API를 사용했는지 감시할 수도 있고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ErrorInFutureSwiftVersion을 주어 특정 경고를 에러로 처리하는것도 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Module Selectors&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 6.3에서는 두 모듈에 동일한 이름의 API 있을때도 더 잘 처리하도록 해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.06.44.png&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/738ji/dJMcadPVJHU/2jEAJiMFQbOqEnpZJnbeLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/738ji/dJMcadPVJHU/2jEAJiMFQbOqEnpZJnbeLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/738ji/dJMcadPVJHU/2jEAJiMFQbOqEnpZJnbeLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F738ji%2FdJMcadPVJHU%2F2jEAJiMFQbOqEnpZJnbeLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;589&quot; height=&quot;356&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.06.44.png&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;같은 파일에 이렇게 두 모듈을 모두 임포트했다고 가정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift는 원래 어떤걸 원하는지 몰라 에러를 내뱉어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래서 우리는 Rocket.SaturnV 이렇게 더 명확한 경로를 주어 사용했죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.08.25.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj33Co/dJMcaiKt0dM/4y7ozpUlHTH4a0P7kBsbAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj33Co/dJMcaiKt0dM/4y7ozpUlHTH4a0P7kBsbAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj33Co/dJMcaiKt0dM/4y7ozpUlHTH4a0P7kBsbAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj33Co%2FdJMcaiKt0dM%2F4y7ozpUlHTH4a0P7kBsbAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;289&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.08.25.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그런데 만약 이렇게 Rocket 모듈안에 Rocket 타입이 있다면?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift는 모듈 이름보다 타입 이름을 더 우선시합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래서 protocol에서 SaturnV를 찾게 되는것이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;없으면 당연히 에러가 나겠죠?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래서 Swift 6.3에서는 더블 콜론 문법을 도입했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.09.53.png&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NCWbF/dJMcajbv65q/G9OSs05Wxr07bo2zHjexH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NCWbF/dJMcajbv65q/G9OSs05Wxr07bo2zHjexH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NCWbF/dJMcajbv65q/G9OSs05Wxr07bo2zHjexH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNCWbF%2FdJMcajbv65q%2FG9OSs05Wxr07bo2zHjexH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;302&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.09.53.png&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 ::으로 경로를 지정하게 되면 모듈을 보게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;모듈 셀렉터라고 불러요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.10.57.png&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bamS75/dJMcabxQsbO/Tk1yHpDblwVsfYtZm5FCWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bamS75/dJMcabxQsbO/Tk1yHpDblwVsfYtZm5FCWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bamS75/dJMcabxQsbO/Tk1yHpDblwVsfYtZm5FCWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbamS75%2FdJMcabxQsbO%2FTk1yHpDblwVsfYtZm5FCWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;691&quot; height=&quot;290&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.10.57.png&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이건 이렇게 메서드나 프로퍼티에서도 사용이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;많이 유용할것 같아요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;예를들어 SwiftUI에서 View 타입이 있는데, 모듈 이름도 View로 짓거나 하고 싶을 수도 있기에 이럴때 선택지가 없었는데 매우 도움이 될것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이제는 Swift 언어에 대한 개선 혹은 신규 사항들을 살펴봤으니, 다음으로 라이브러리에 대한 새로운 사항들을 살펴볼까요?  &lt;/span&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Libraries&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Standard Library&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.59.23.png&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJgnBR/dJMcabxQte5/ja3hGlHyyZxv0yX3KmhtUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJgnBR/dJMcabxQte5/ja3hGlHyyZxv0yX3KmhtUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJgnBR/dJMcabxQte5/ja3hGlHyyZxv0yX3KmhtUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJgnBR%2FdJMcabxQte5%2Fja3hGlHyyZxv0yX3KmhtUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;391&quot; height=&quot;343&quot; data-filename=&quot;스크린샷 2026-06-22 오전 10.59.23.png&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제 Task 취소 쉴드 기능을 사용할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;쉴드 내부에선 작업 취소 확인이 항상 false로 반환됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이미 시작한 작업을 완료하거나 롤백하는데 중요시 생각해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.01.11.png&quot; data-origin-width=&quot;1682&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bslw4S/dJMcajbv8FI/bROlw0x9f2JHvViS1tdxRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bslw4S/dJMcajbv8FI/bROlw0x9f2JHvViS1tdxRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bslw4S/dJMcajbv8FI/bROlw0x9f2JHvViS1tdxRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbslw4S%2FdJMcajbv8FI%2FbROlw0x9f2JHvViS1tdxRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;120&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.01.11.png&quot; data-origin-width=&quot;1682&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;해당 mapKeyedValues가 생겼어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이걸 활용하면 키와 이전 값 모두 매핑 클로저에 전달해 새 값을 계산할 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.02.49.png&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba9a1g/dJMcadPVLiK/ltDK2iRQ3PNJup7O89t5T1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba9a1g/dJMcadPVLiK/ltDK2iRQ3PNJup7O89t5T1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba9a1g/dJMcadPVLiK/ltDK2iRQ3PNJup7O89t5T1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba9a1g%2FdJMcadPVLiK%2FltDK2iRQ3PNJup7O89t5T1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;230&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.02.49.png&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;플랫폼 마다 파일 경로를 나타내는것이 다를 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;올바르게 처리하기 까다로울 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제는 Swift System의 타입을 기반으로 표준 라이브러리에 새로운 filepath 타입을 추가해 더욱 적절히 사용할 수 있게 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Testing&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 6.4의 테스팅은 테스트 동작에 대한 더 많은 제어권을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.05.02.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ll1UB/dJMcajimTaj/wGiXorjF8Uwu8w76uHK6D0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ll1UB/dJMcajimTaj/wGiXorjF8Uwu8w76uHK6D0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ll1UB/dJMcajimTaj/wGiXorjF8Uwu8w76uHK6D0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLl1UB%2FdJMcajimTaj%2FwGiXorjF8Uwu8w76uHK6D0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;686&quot; height=&quot;299&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.05.02.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Issue.record를 통해 치명적이지 않은 이슈들은 그냥 워닝으로만으로 설정할 수 도 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;CI 워크플로우를 방해하지 않게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그리고 Test.cancel API가 생겨서 테스트를 동적으로 취소할 수도 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.06.47.png&quot; data-origin-width=&quot;1454&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6kHJH/dJMcaglCXwE/qjlt1WibdnAXQLRKT80UwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6kHJH/dJMcaglCXwE/qjlt1WibdnAXQLRKT80UwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6kHJH/dJMcaglCXwE/qjlt1WibdnAXQLRKT80UwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6kHJH%2FdJMcaglCXwE%2Fqjlt1WibdnAXQLRKT80UwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;362&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.06.47.png&quot; data-origin-width=&quot;1454&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift test 명령어에 테스트를 반복하는 새로운 기능도 생겼습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.08.39.png&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deChNa/dJMcahkCC7F/YqYl4X6j5YNcX8gMyIkRK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deChNa/dJMcahkCC7F/YqYl4X6j5YNcX8gMyIkRK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deChNa/dJMcahkCC7F/YqYl4X6j5YNcX8gMyIkRK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdeChNa%2FdJMcahkCC7F%2FYqYl4X6j5YNcX8gMyIkRK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;246&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.08.39.png&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift Test로 사용되는것들도 상호운용성 덕에 XCTest에서도 동일하게 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Subprocess&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지난해 Subprocess 패키지를 애플이 발표했어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;쉽게 서브프로세스를 실행 시키기 위한 API를 포함한 패키지죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;올해 Subprocess 1.0을 출시합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.10.38.png&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciKBBt/dJMcaf1i7Wo/Czzs3hMiRM8KOy1sQcwDAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciKBBt/dJMcaf1i7Wo/Czzs3hMiRM8KOy1sQcwDAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciKBBt/dJMcaf1i7Wo/Czzs3hMiRM8KOy1sQcwDAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciKBBt%2FdJMcaf1i7Wo%2FCzzs3hMiRM8KOy1sQcwDAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;410&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.10.38.png&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;피드백을 중점으로 여러 사항들이 개선되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;특히 크로스 플랫폼 지원도 강력해졌어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.11.46.png&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3hcd8/dJMcaff1mz2/YSE8spXosK6YHsYvZn3fH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3hcd8/dJMcaff1mz2/YSE8spXosK6YHsYvZn3fH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3hcd8/dJMcaff1mz2/YSE8spXosK6YHsYvZn3fH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3hcd8%2FdJMcaff1mz2%2FYSE8spXosK6YHsYvZn3fH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1510&quot; height=&quot;556&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.11.46.png&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;556&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;예시로, 서브프로세스를 실행하기 위해 run 메서드를 호출할 때 표준 출력과 표준 오류 스트림을 AsyncBufferSequence로 실행 객체에 포함할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 모델은 각 스트림이 단 한번만 생성됨을 보장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;strings() 메서드로 서브 프로세스를 라인 바이 라인으로 쉽게 읽을 수 있도록 보장해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Foundation&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.14.19.png&quot; data-origin-width=&quot;1348&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbG5Oq/dJMcag0cGCi/FG8cPtakdmEVNINkKAQv9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbG5Oq/dJMcag0cGCi/FG8cPtakdmEVNINkKAQv9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbG5Oq/dJMcag0cGCi/FG8cPtakdmEVNINkKAQv9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbG5Oq%2FdJMcag0cGCi%2FFG8cPtakdmEVNINkKAQv9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1348&quot; height=&quot;584&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.14.19.png&quot; data-origin-width=&quot;1348&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ProgressManager라는게 Foundation 라이브러리 내에 생겼습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;진행 상황 보고를 위한 새 타입이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift Concurrency로 설계되고 구조화되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.17.06.png&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6i0VW/dJMcahx6JmP/QzVgg4PVted1VkSSMqr9O1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6i0VW/dJMcahx6JmP/QzVgg4PVted1VkSSMqr9O1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6i0VW/dJMcahx6JmP/QzVgg4PVted1VkSSMqr9O1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6i0VW%2FdJMcahx6JmP%2FQzVgg4PVted1VkSSMqr9O1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;916&quot; height=&quot;530&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.17.06.png&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;또한, Foundation에서 Data 부분도 더 개선되어 빨라졌습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Data와 NSData의 브릿징도 감소되었고 NSURL과 CFURL도 Swift에서 통합되었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이런 큰 Foundation을 개선할 수 있는건 Swift의 언어 상호운용성 덕분에 가능하죠.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.19.15.png&quot; data-origin-width=&quot;1798&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIEC7e/dJMcadoRbc2/4qm5qjmsgctS7hCi17W5B1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIEC7e/dJMcadoRbc2/4qm5qjmsgctS7hCi17W5B1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIEC7e/dJMcadoRbc2/4qm5qjmsgctS7hCi17W5B1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIEC7e%2FdJMcadoRbc2%2F4qm5qjmsgctS7hCi17W5B1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1798&quot; height=&quot;432&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.19.15.png&quot; data-origin-width=&quot;1798&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;언어의 경계를 넘어 의미있는 크로스 플랫폼의 언어로 진화하고 있죠.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Full-stack Swift&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Interoperability&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift는 정말 어떤 분야도 막힐게 없는 풀스택 언어가 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;특히 Swift 6.4에서는 언어 상호 운용성을 더 극대화 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;크로스 플랫폼 IDE 지원을 개선하고 더 쉽고 안전하게 웹이나 임베디드 기기와 같은 다른 환경에 Swift 코드를 가져갈 수 있게 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 6.4는 Swift로 작성된걸 C에 노출할 수 있게 합니다. (반대는 이미 가능했어요.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.22.22.png&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwEasK/dJMcag60dno/FeK77ZK22Ukj2jke1HStX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwEasK/dJMcag60dno/FeK77ZK22Ukj2jke1HStX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwEasK/dJMcag60dno/FeK77ZK22Ukj2jke1HStX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwEasK%2FdJMcag60dno%2FFeK77ZK22Ukj2jke1HStX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;314&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.22.22.png&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 @c를 통해 사용할 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.23.56.png&quot; data-origin-width=&quot;1724&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VrXTO/dJMcabECGX0/dyKCSaGshQkbbmKTbuAjg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VrXTO/dJMcabECGX0/dyKCSaGshQkbbmKTbuAjg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VrXTO/dJMcabECGX0/dyKCSaGshQkbbmKTbuAjg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVrXTO%2FdJMcabECGX0%2FdyKCSaGshQkbbmKTbuAjg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1724&quot; height=&quot;920&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.23.56.png&quot; data-origin-width=&quot;1724&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;@c와 @implementation 어노테이션을 사용하면 별도 C 선언 없이도 C 함수 구현이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;원래 헤더 파일에 이미 선언되어 있었으니까요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;만약 원래 C 헤더에 선언되어 있지 않았던거라면 @c만으로 충분하고 @implementation을 사용하지 않아야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇듯 Swift의 상호 운용성은 다른 언어로 작성된 코드 베이스에 Swift를 도입하는데 핵심입니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.26.52.png&quot; data-origin-width=&quot;1704&quot; data-origin-height=&quot;846&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSIqwl/dJMb991amSD/tkMKb4HaB16V38jgh6p0hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSIqwl/dJMb991amSD/tkMKb4HaB16V38jgh6p0hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSIqwl/dJMb991amSD/tkMKb4HaB16V38jgh6p0hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSIqwl%2FdJMb991amSD%2FtkMKb4HaB16V38jgh6p0hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1704&quot; height=&quot;846&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.26.52.png&quot; data-origin-width=&quot;1704&quot; data-origin-height=&quot;846&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift-Java는 Swift와 Java 사이 상호 운용성을 가능케 하는 패키지입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Java에서 async와 throwing Swift 함수 호출을 할 수 있게 지원해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그 외 Java 클래스를 Swift 프로토콜에 적합하게 만드는것도 가능하고요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;즉 이제, Java, Kotlin 환경에서 Swift 함수를 호출하는것이 자연스러워진것입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Editor Support&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;VSCode용 Swift 익스텐션 최신 버전이 Swiftly와 새로운 통합을 추가합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;에디터에서 바로 swift.org의 툴체인을 쉽게 받아볼 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제 어떤 에디터든 정확한 툴체인을 받아 볼 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Wasm&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;오픈 소스 툴체인으로 Web Assembly로 컴파일 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift의 Wasm 지원은 동일한 언어로 네이티브 앱을 작성하고 BE, FE 모두 작성할 수 있는것이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Embedded&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;더 제한된 환경에서도 Swift의 편의성을 활용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.37.10.png&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFzYH2/dJMcaaeHjkg/MWCiIRabAb6jDUuGJq6Sjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFzYH2/dJMcaaeHjkg/MWCiIRabAb6jDUuGJq6Sjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFzYH2/dJMcaaeHjkg/MWCiIRabAb6jDUuGJq6Sjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFzYH2%2FdJMcaaeHjkg%2FMWCiIRabAb6jDUuGJq6Sjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;595&quot; height=&quot;475&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.37.10.png&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;604&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;임베디드 Swift는 이제 existential 타입을 지원합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;프로토콜을 준수하는 여러 타입을 사용할 수 있게 된거죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 6.4는 필요한 모든 메타 데이터를 DWARF 디버그 정보에 저장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;임베디드 Swift 코어 덤프 디버깅 경험에 도움을 주죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이제 Swift 성능을 극대화하는 방법들을 들어볼까요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Performance ergonomics&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Optimizer controls&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 컴파일러의 optimizer는 코드를 더 빠르게 만들기 위해 수십 가지 기법을 적용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그치만 잘못 적용하면 오히려 역효과가 날 수도 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.45.42.png&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;918&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBAyLP/dJMcaiDMggr/e7ndq7hSCvdgkvd2aCdDxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBAyLP/dJMcaiDMggr/e7ndq7hSCvdgkvd2aCdDxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBAyLP/dJMcaiDMggr/e7ndq7hSCvdgkvd2aCdDxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBAyLP%2FdJMcaiDMggr%2Fe7ndq7hSCvdgkvd2aCdDxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1652&quot; height=&quot;918&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.45.42.png&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;918&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;예를들어, 컴파일러가 수행하는 가장 최적화중 하나는 인라이닝입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;함수 호출 코드 위치를 대체하고 특정 위치에 맞게 최적화하는거죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;만약 역효과가 난다면 더 빨라지진 않고 바이너리만 크게 만들 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래서 이게 효과적일지를 판단하기 위해 함수와 호출 위치를 분석해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;때론 잘못 판단할 수도 있기에 강제로 적용하는게 필요할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.48.08.png&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWQSVL/dJMcafG5rsu/e3hKXmd8Nb2ZYTZy1Ba0Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWQSVL/dJMcafG5rsu/e3hKXmd8Nb2ZYTZy1Ba0Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWQSVL/dJMcafG5rsu/e3hKXmd8Nb2ZYTZy1Ba0Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWQSVL%2FdJMcafG5rsu%2Fe3hKXmd8Nb2ZYTZy1Ba0Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1134&quot; height=&quot;518&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.48.08.png&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 6.4에서 @inline(always) 기능이 생겼습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;기존에는 @inline(never) 속성만 있었고 대부분 이게 권장되었었는데 이제는 명시적으로 필요할 수 있다는걸 의미하는거죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래서 이걸 사용할 때 웬만하면 final 키워드와 같이 사용하는걸 권장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.50.36.png&quot; data-origin-width=&quot;1666&quot; data-origin-height=&quot;806&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbDPrF/dJMcabxQu0u/R7Rhx9XLT1NctRx62kG2y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbDPrF/dJMcabxQu0u/R7Rhx9XLT1NctRx62kG2y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbDPrF/dJMcabxQu0u/R7Rhx9XLT1NctRx62kG2y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbDPrF%2FdJMcabxQu0u%2FR7Rhx9XLT1NctRx62kG2y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1666&quot; height=&quot;806&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.50.36.png&quot; data-origin-width=&quot;1666&quot; data-origin-height=&quot;806&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;또 다른 최적화는 특수화입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 제네릭 오버헤드를 없애고 추가 최적화를 가능하게 해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.51.36.png&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rx2Bl/dJMcafNSt10/396IOKB95dkDXPquVVIX8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rx2Bl/dJMcafNSt10/396IOKB95dkDXPquVVIX8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rx2Bl/dJMcafNSt10/396IOKB95dkDXPquVVIX8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frx2Bl%2FdJMcafNSt10%2F396IOKB95dkDXPquVVIX8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1654&quot; height=&quot;732&quot; data-filename=&quot;스크린샷 2026-06-22 오전 11.51.36.png&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;하지만 때론 라이브러리에서 컴파일러가 함수를 어떻게 사용할 지 모를 수 있기에, 이를 직접 제어하기 위해 @specialized 어노테이션을 붙여 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Ownership enhancements&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;가장 큰 성능 향상을 이룬 개선을 살펴보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;바로 소유권 시스템입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift의 성능 문제는 대부분 복사 때문에 코스트가 발생하죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.30.59.png&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwqLpV/dJMcaf736iU/zgAJdGRHyerRxNfQFCpbD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwqLpV/dJMcaf736iU/zgAJdGRHyerRxNfQFCpbD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwqLpV/dJMcaf736iU/zgAJdGRHyerRxNfQFCpbD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwqLpV%2FdJMcaf736iU%2FzgAJdGRHyerRxNfQFCpbD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1240&quot; height=&quot;670&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.30.59.png&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이런식은 다들 너무 잘 알거기에 긴 설명이 필요 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;복사로 인해 성능 저하를 해결하는 방법은 특정 상황에서 복사가 필요없다는걸 인식해야 해요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.34.27.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0wDr5/dJMcaaFNxL8/E4kZZVQW1BFFLBGKS8ZSuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0wDr5/dJMcaaFNxL8/E4kZZVQW1BFFLBGKS8ZSuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0wDr5/dJMcaaFNxL8/E4kZZVQW1BFFLBGKS8ZSuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0wDr5%2FdJMcaaFNxL8%2FE4kZZVQW1BFFLBGKS8ZSuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1032&quot; height=&quot;666&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.34.27.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure data-ke-type=&quot;image&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; data-ke-style=&quot;alignCenter&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot; class=&quot;bar_progress&quot;&gt;&lt;/span&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 복사를 피해 데이터를 객체에 넣어 그 객체를 다른 컴포넌트에 전달하는 방식으로도 할 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;대부분의 경우는 해결할 수 있지만 모든 경우는 아니에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;객체에 참조 카운트가 있어 전달하면 참조 카운트가 변경되기에 그렇죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.36.19.png&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MUjNS/dJMcag0cRqD/QytoXuaaiehPi0HaH4PzG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MUjNS/dJMcag0cRqD/QytoXuaaiehPi0HaH4PzG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MUjNS/dJMcag0cRqD/QytoXuaaiehPi0HaH4PzG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMUjNS%2FdJMcag0cRqD%2FQytoXuaaiehPi0HaH4PzG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1262&quot; height=&quot;672&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.36.19.png&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래서 요즘 방식은 Borrow를 이용하는 겁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;컴포넌트 2가 저장소 자체를 빌리는 동안은 컴포넌트 모두 읽기만 가능하고 쓸 순 없어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;컴포넌트 2가 먼저 끝내야 컴포넌트 1이 제어권을 가지게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.37.32.png&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT8Ja2/dJMcacp3F6u/xmX6MQ5uxpXbtdjSTLKIa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT8Ja2/dJMcacp3F6u/xmX6MQ5uxpXbtdjSTLKIa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT8Ja2/dJMcacp3F6u/xmX6MQ5uxpXbtdjSTLKIa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT8Ja2%2FdJMcacp3F6u%2FxmX6MQ5uxpXbtdjSTLKIa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1198&quot; height=&quot;660&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.37.32.png&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Mutate도 있는데, 다른 컴포넌트가 저장소에 접근하는것 자체도 완전 차단됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.39.09.png&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b25F3m/dJMcaaeHuyR/GVAvk37YFTLH6jNgQ228p0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b25F3m/dJMcaaeHuyR/GVAvk37YFTLH6jNgQ228p0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b25F3m/dJMcaaeHuyR/GVAvk37YFTLH6jNgQ228p0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb25F3m%2FdJMcaaeHuyR%2FGVAvk37YFTLH6jNgQ228p0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1458&quot; height=&quot;388&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.39.09.png&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 연관 타입도 이제 복사 불가능, 이스케피이 불가능 등을 지정할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.41.05.png&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN2MoB/dJMcaaloxcJ/wVkpGjIdSzwRRQLvX9KGvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN2MoB/dJMcaaloxcJ/wVkpGjIdSzwRRQLvX9KGvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN2MoB/dJMcaaloxcJ/wVkpGjIdSzwRRQLvX9KGvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN2MoB%2FdJMcaaloxcJ%2FwVkpGjIdSzwRRQLvX9KGvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1296&quot; height=&quot;766&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.41.05.png&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;복사 없이 for문 안에서 반복이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Sequence처럼 Iterable은 이터레이터를 생성해 for문이 요소를 가져오도록 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;하지만, 시퀀스하곤 달리 요소들을 배치로 가져옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.43.36.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2DIxm/dJMcaiqd59j/67k5kK265KX2r4SZeVOTf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2DIxm/dJMcaiqd59j/67k5kK265KX2r4SZeVOTf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2DIxm/dJMcaiqd59j/67k5kK265KX2r4SZeVOTf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2DIxm%2FdJMcaiqd59j%2F67k5kK265KX2r4SZeVOTf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;194&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.43.36.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;또한, borrow, mutate라는 새로운 접근제어자가 생겼어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;borrow는 공유 저장소에 대한 읽기 전용으로 동작합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;복사 없이요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;mutate는 수정도 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;위에 우리가 살펴봤던것과 동일해요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.48.44.png&quot; data-origin-width=&quot;1570&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GeSZ4/dJMcaay0f3T/v2vwLWc6AtW1P7Q8pkM7m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GeSZ4/dJMcaay0f3T/v2vwLWc6AtW1P7Q8pkM7m1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GeSZ4/dJMcaay0f3T/v2vwLWc6AtW1P7Q8pkM7m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGeSZ4%2FdJMcaay0f3T%2Fv2vwLWc6AtW1P7Q8pkM7m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1570&quot; height=&quot;796&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.48.44.png&quot; data-origin-width=&quot;1570&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;또한 성능을 위한 대체 API들도 나왔으니 적극 활용해보면 좋을것 같아요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.50.36.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FeIVM/dJMcaf739gx/qPE3lCqGOi3wMnfJQKEVS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FeIVM/dJMcaf739gx/qPE3lCqGOi3wMnfJQKEVS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FeIVM/dJMcaf739gx/qPE3lCqGOi3wMnfJQKEVS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFeIVM%2FdJMcaf739gx%2FqPE3lCqGOi3wMnfJQKEVS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;606&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.50.36.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Ref와 MutableRef 타입을 통해 저장소에 접근도 제어할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이전에는 이런식으로 활용되었죠.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.51.46.png&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cT8GGq/dJMb997S8CF/Qsq0nZwKHMZGoXrwkA71Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cT8GGq/dJMb997S8CF/Qsq0nZwKHMZGoXrwkA71Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cT8GGq/dJMb997S8CF/Qsq0nZwKHMZGoXrwkA71Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcT8GGq%2FdJMb997S8CF%2FQsq0nZwKHMZGoXrwkA71Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;978&quot; height=&quot;674&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.51.46.png&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;inout을 통해서 말이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.52.52.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3dfnB/dJMcacp3Ik5/dPi36Nv8PKNd046RXFlOHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3dfnB/dJMcacp3Ik5/dPi36Nv8PKNd046RXFlOHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3dfnB/dJMcacp3Ik5/dPi36Nv8PKNd046RXFlOHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3dfnB%2FdJMcacp3Ik5%2FdPi36Nv8PKNd046RXFlOHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1032&quot; height=&quot;614&quot; data-filename=&quot;스크린샷 2026-06-22 오후 1.52.52.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이제는 MutableRef를 사용하여 보다 간단하게 표현할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Conclustion&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 이번 WWDC 2026에서 소개된 Swift 파트를 살펴봤습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그렇게 큰 변경이나 그런건 없어보여요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;틈틈히 Swift 6.3, Swift 6.4 릴리즈에 대한것들을 정리하고 살펴본적이 있어서 그런지 리캡 느낌이였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그래도 성능 부분에서 어떻게 언어적으로 잘 쓸 수 있는지에 대해 고민해보게 되고, 크로스 플랫폼 언어로 진화됨에 따라 앞으로는 더욱 포지션 별, 플랫폼 별 구분이 사라지는데 제약이 없을것 같다고 느껴지네요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1782104140244&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Swift의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&quot; data-og-description=&quot;Swift 관련 업데이트를 확인해 보세요. 일상적인 인체공학, 향상된 동시성, 더 안전한 고성능 코드를 위한 업데이트 등 언어 관련 최신 혁신 기술을 알아보세요. Embedded Swift의 워크플로와 언어 상&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot; data-og-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kyB4C/dJMb87gf74E/PnnNbXmn7DY52TZS9kKRQk/img.jpg?width=500&amp;amp;height=282&amp;amp;face=0_0_500_282,https://scrap.kakaocdn.net/dn/gDaX7/dJMb8XSfvrL/9HOMkuuKFhUyKMYAzPlGc1/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=0_0_1800_1012&quot;&gt;&lt;a href=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/kr/videos/play/wwdc2026/262/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kyB4C/dJMb87gf74E/PnnNbXmn7DY52TZS9kKRQk/img.jpg?width=500&amp;amp;height=282&amp;amp;face=0_0_500_282,https://scrap.kakaocdn.net/dn/gDaX7/dJMb8XSfvrL/9HOMkuuKFhUyKMYAzPlGc1/img.jpg?width=1800&amp;amp;height=1012&amp;amp;face=0_0_1800_1012');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Swift의 새로운 기능 - WWDC26 - 비디오 - Apple Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Swift 관련 업데이트를 확인해 보세요. 일상적인 인체공학, 향상된 동시성, 더 안전한 고성능 코드를 위한 업데이트 등 언어 관련 최신 혁신 기술을 알아보세요. Embedded Swift의 워크플로와 언어 상&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Swift</category>
      <category>Apple</category>
      <category>ios</category>
      <category>SWIFT</category>
      <category>Swift6.3</category>
      <category>Swift6.4</category>
      <category>what's new in swift</category>
      <category>WWDC 2026</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/625</guid>
      <comments>https://green1229.tistory.com/625#entry625comment</comments>
      <pubDate>Mon, 22 Jun 2026 14:00:01 +0900</pubDate>
    </item>
    <item>
      <title>[SE-0531] Literal Expressions</title>
      <link>https://green1229.tistory.com/624</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 포스팅에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;SE-0531 &amp;mdash; Literal Expressions&lt;/b&gt;&lt;/span&gt;에 대해 정리해보겠습니다  &lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tiOTN/dJMcafNRW2W/5bJgOdLfudHDmS6s0uL761/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tiOTN/dJMcafNRW2W/5bJgOdLfudHDmS6s0uL761/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tiOTN/dJMcafNRW2W/5bJgOdLfudHDmS6s0uL761/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtiOTN%2FdJMcafNRW2W%2F5bJgOdLfudHDmS6s0uL761%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposal:&lt;/b&gt; SE-0531&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Authors:&lt;/b&gt; Artem Chikin, Doug Gregor&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Review Manager:&lt;/b&gt; Ben Cohen&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Status:&lt;/b&gt; Active Review (May 18...29, 2026)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift에는 정수 리터럴 값만 허용하는 세 가지 문법 컨텍스트가 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;generic value arguments(SE-0452), @section 변수(SE-0492), enum raw value.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지금까지는 개발자가 직접 값을 계산해서 &lt;b&gt;bare literal로 손수 옮겨 적어야&lt;/b&gt; 했어요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 과정에서 값이 의미하는 바가 사라지고, 코드 전반에 &quot;매직 넘버&quot;가 퍼지게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;@section과 컴파일타임 초기화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;@section&lt;/code&gt;은 페이지 크기, 레지스터 오프셋처럼 다른 상수로부터 값이 파생되는 시스템/임베디드 환경을 겨냥한 어트리뷰트입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;하지만 지금은 연산자나 변수 참조를 전혀 허용하지 않아요.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;@section(&quot;__DATA,config&quot;) let pageSize = 4096
@section(&quot;__DATA,config&quot;) let bufferSize = 65536
@section(&quot;__DATA,config&quot;) let c = 1 + 1  // ❌ error: operators not allowed&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;4096&lt;/code&gt;이 &lt;i&gt;4 &amp;times; 1024&lt;/i&gt;라는 사실도, &lt;code&gt;bufferSize&lt;/code&gt;가 &lt;i&gt;16 &amp;times; pageSize&lt;/i&gt;라는 관계도 코드만 봐서는 전혀 알 수 없었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Enum raw value&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 1.0부터 enum raw value는 순수 리터럴만 허용했습니다. bit-flag enum처럼 shift 표현이 자연스러운 경우조차 표현할 방법이 없었어요.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;crystal&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;enum Permissions: Int {
  case read = 1
  case write = 2
  case execute = 4
}
// 1 &amp;lt;&amp;lt; 0, 1 &amp;lt;&amp;lt; 1, 1 &amp;lt;&amp;lt; 2 라고 쓰는 게 훨씬 의도가 명확한데도 불가능했어요&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;정수 제네릭 인자&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;SE-0452가 도입한 정수 제네릭 파라미터도 마찬가지로 bare integer literal만 허용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;let schemaRowSize = 32

// 원하는 것: InlineArray&amp;lt;(2 * schemaRowSize), UInt8&amp;gt;
let buffer: InlineArray&amp;lt;64, UInt8&amp;gt;  // 64 == 2 * 32 이길 바랄 뿐...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;세 가지 컨텍스트 모두 같은 근본적인 제약을 공유합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;개발자가 사람 계산기 역할을 해야 했고, 그 값이 왜 그 숫자인지에 대한 의도는 사라져버렸어요  &lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposed Solution&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 제안은 &lt;b&gt;Literal Expression(리터럴 표현식)&lt;/b&gt;을 도입합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;표준 라이브러리 정수 타입의 리터럴, 산술/비트 연산자, 그리고 컴파일타임에 알려진 다른 정수 변수 참조로 구성된 표현식이에요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 표현식은 컴파일 타임에 &lt;b&gt;단일 리터럴 값으로 상수 폴딩&lt;/b&gt;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// @section &amp;mdash; 연산과 변수 참조 모두 가능
@section(&quot;__DATA,config&quot;) let pageSize = 4 * 1024
@section(&quot;__DATA,config&quot;) let bufferSize = 16 * pageSize

// enum raw value &amp;mdash; shift 표현이 가능
enum Permissions: Int {
  case read    = 1 &amp;lt;&amp;lt; 0
  case write   = 1 &amp;lt;&amp;lt; 1
  case execute = 1 &amp;lt;&amp;lt; 2
}

// 정수 제네릭 &amp;mdash; 괄호로 감싼 표현식 허용
let schemaRowSize = 32
let buffer: InlineArray&amp;lt;(2 * schemaRowSize), UInt8&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;중요한 점은, literal expression을 사용해 컴파일된 모듈은 &lt;b&gt;개발자가 직접 미리 계산한 리터럴을 쓴 모듈과 완전히 동일한 산출물&lt;/b&gt;을 만들어낸다는 거예요.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Detailed Design&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Literal Expression의 문법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;mel&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;literal-expression &amp;rarr; integer-literal
literal-expression &amp;rarr; unary-operator literal-expression
literal-expression &amp;rarr; literal-expression binary-operator literal-expression
literal-expression &amp;rarr; '(' literal-expression ')'
literal-expression &amp;rarr; identifier&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지원하는 연산자: 산술(+ - * / %), wrapping(&amp;amp;+ &amp;amp;- &amp;amp;*), 비트(&amp;amp; | ^), shift(&amp;lt;&amp;lt; &amp;gt;&amp;gt;), masking shift(&amp;amp;&amp;lt;&amp;lt; &amp;amp;&amp;gt;&amp;gt;), 단항(+ - ~).&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;일반 산술 연산자는 오버플로우를 &lt;b&gt;컴파일 타임에 진단&lt;/b&gt;하고, wrapping 연산자는 결과를 타입의 비트 너비로 silent하게 모듈러 처리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;let a = 4 * 1024                  // ✅ 산술
let b = 1 &amp;lt;&amp;lt; 12                   // ✅ 비트 시프트
let c = (0xFF &amp;amp; mask) | base      // ✅ 비트 연산 + 괄호
let d = -1                        // ✅ 단항 부정
let w: UInt8 = 250 &amp;amp;+ 10          // ✅ wrapping 덧셈, 4로 폴딩
let e = Int.max / 2               // ❌ 프로퍼티 접근 불가
let f = a +% b                    // ❌ 사용자 정의 연산자 불가&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;연산자 lookup은 Swift의 일반 name lookup 규칙을 그대로 따릅니다. 만&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;약 lookup이 사용자 정의 오버로드로 해석되면, 표준 라이브러리 오버로드가 스코프에 같이 있더라도 &lt;b&gt;전체 표현식이 거부&lt;/b&gt;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Literal Expression 내 변수 참조&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;literal expression은 다른 변수를 이름으로 참조할 수 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;단, 그 변수가 &lt;code&gt;let&lt;/code&gt; 바인딩이고, 기본 초기화 값 자체도 literal expression이어야 해요.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;let pageSize = 4 * 1024
let bufferSize = 16 * pageSize             // ✅ pageSize 참조

import CSystem
let systemBuffer = 4 * SYSTEM_PAGE_SIZE    // ✅ C 상수

var mutableSize = 4096
let derived = 2 * mutableSize              // ❌ var는 참조 불가

let computed: Int = { 4096 }()             // ❌ 초기화식이 literal expression이 아님
let derived2 = 2 * computed&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;주의할 점&lt;/b&gt; &amp;mdash; &lt;code&gt;public&lt;/code&gt;, &lt;code&gt;package&lt;/code&gt;, &lt;code&gt;open&lt;/code&gt; 접근 수준의 변수는 literal expression에서 참조할 수 없습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;폴딩이 일어나면 해당 변수의 초기화식이 모듈의 ABI 표면에 노출되는 셈인데, 이는 이 제안의 &quot;ABI 변경 없음&quot; 원칙과 충돌하기 때문이에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;@section 변수 초기화식&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;@section(&quot;__TEXT,config&quot;) let pageSize = 4 * 1024
@section(&quot;__TEXT,config&quot;) let bufferSize = 16 * pageSize
@section(&quot;__TEXT,config&quot;) let systemPage = PAGE_SIZE    // C 상수&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;원본 표현식은 진단과 IDE 인덱싱을 위해 AST에 보존되지만, &lt;code&gt;.swiftinterface&lt;/code&gt; 파일에는 출력되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Enum raw value&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;enum Permissions: UInt8 {
  case read    = 1 &amp;lt;&amp;lt; 0    // 1
  case write   = 1 &amp;lt;&amp;lt; 1    // 2
  case execute = 1 &amp;lt;&amp;lt; 2    // 4
}

enum Example: Int {
  case a = 2 + 2    // 4
  case b            // 5
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;정수 제네릭 인자&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;delphi&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;generic-argument &amp;rarr; type
generic-argument &amp;rarr; '-'? integer-literal
generic-argument &amp;rarr; '(' literal-expression ')'   // 새로 추가된 형태&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭 인자 위치에서는 &amp;lt;, &amp;gt;, , 토큰이 구분자 역할을 하기 때문에, literal expression은 &lt;b&gt;반드시 괄호로 감싸야&lt;/b&gt; 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;clean&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;let schemaRowSize = 32
let buffer: InlineArray&amp;lt;(2 * schemaRowSize), UInt8&amp;gt;    // ✅
let flags: InlineArray&amp;lt;(1 &amp;lt;&amp;lt; 4), Bool&amp;gt;                 // ✅
let small: InlineArray&amp;lt;5, Int&amp;gt;                         // ✅ 기존처럼 괄호 없이도 동작&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;폴딩된 값이 곧 타입 동일성을 결정합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;InlineArray&amp;lt;(2 + 3), Int&amp;gt;&lt;/code&gt;와 &lt;code&gt;InlineArray&amp;lt;5, Int&amp;gt;&lt;/code&gt;는 동일한 타입이에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;컴&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;파일타임 진단&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;xquery&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;let x: UInt8 = 100 * 3    // ❌ error: integer overflow
let y = 10 / 0           // ❌ error: division by zero
let z = 10 % 0           // ❌ error: division by zero

@section(&quot;__TEXT,data&quot;) let a = abs(-1)    // ❌ error: not supported in a literal expression&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Source Compatibility&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 변경은 세 가지 표현식 컨텍스트를 확장할 뿐, 다른 곳에서 받아들여지던 표현식 형태를 제거하거나 바꾸지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;흥미로운 케이스 하나는 제네릭 인자 목록의 모호성 해소입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;컴파일러는 괄호 안의 내용을 &lt;b&gt;먼저 타입 표현식(튜플)으로 해석&lt;/b&gt;을 시도하고, 실패할 때만 literal expression으로 해석합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;예를 들어 &lt;code&gt;Foo&amp;lt;(a &amp;lt; b, c &amp;gt; .d)&amp;gt;(x)&lt;/code&gt; 같은 코드는 &lt;b&gt;기존의 체이닝 비교 연산으로 폴백&lt;/b&gt;되어 의미가 바뀌지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;ABI Compatibility&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;literal expression은 &lt;b&gt;컴파일러 프론트엔드 내에서 완전히 폴딩&lt;/b&gt;되며, 코드 생성&amp;middot;런타임&amp;middot;심볼 맹글링에 변화가 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;정수 제네릭 인자의 경우 &lt;b&gt;폴딩된 값&lt;/b&gt;이 모듈 인터페이스에 타입의 일부로 나타납니다 (예: InlineArray&amp;lt;5, Int&amp;gt;).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;@section 변수와 enum raw value는 원본 표현식도, 폴딩된 상수도 모듈 인터페이스에 나타나지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Implications on Adoption&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 기능은 &lt;code&gt;LiteralExpressions&lt;/code&gt; 실험적 기능 플래그로 게이팅되어 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;폴딩이 컴파일 타임에 일어나고 생성되는 코드가 직접 작성한 리터럴과 동일하기 때문에, &lt;b&gt;최소 배포 타겟 제약이 없습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Future Directions&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;괄호 제약 완화&lt;/b&gt; &amp;mdash; 제네릭 인자 위치에서 &amp;gt;, ==, , 를 stop 토큰으로 처리해 InlineArray&amp;lt;2 + 3, Int&amp;gt;처럼 괄호 없이도 파싱 가능하게 만드는 방향&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;부동소수점 literal expression&lt;/b&gt; &amp;mdash; Float, Double에 대한 산술 연산 지원&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;문자열 literal expression&lt;/b&gt; &amp;mdash; 컴파일타임 문자열 연결 및 보간&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;비교 연산자 및 표준 함수 지원 확대&lt;/b&gt; &amp;mdash; ==, min(), max() 등, 나아가 컴파일타임 Bool을 활용한 삼항 연산자 및 if/else 표현식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;컴파일타임 프로그래밍&lt;/b&gt; &amp;mdash; SE-0359와 연계해 사용자 정의 순수 함수, 풍부한 데이터 타입까지 포괄하는 일반적인 컴파일타임 프로그래밍 모델로의 확장&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Alternatives Considered&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;참조되는 모든 변수에 명시적 어노테이션 요구&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;@const&lt;/code&gt; 같은 명시적 어노테이션을 요구하는 방식도 고려되었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;하지만 SE-0359 리뷰에서 이런 어노테이션의 &lt;b&gt;&quot;전염성(virality)&quot;&lt;/b&gt;이 핵심 우려로 지적된 바 있어요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;literal expression의 경우 어노테이션이 컴파일러가 이미 알고 있는 정보 이상을 제공하지 않기 때문에, &lt;b&gt;추론만으로 충분하다&lt;/b&gt;고 판단해 채택하지 않았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;&quot;Constant Expression&quot; 대신 &quot;Literal Expression&quot; 용어 사용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;C/C++의 전통을 따라 &quot;constant expression&quot;이라는 용어를 쓰는 방법도 있었지만, 스코프와 과대 약속의 위험이라는 두 가지 이유로 &quot;literal expression&quot;을 선택했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift가 향후 더 큰 컴파일타임 개념을 도입할 때를 위해 &quot;constant expression&quot;이라는 이름을 아껴두는 것이 합리적이라고 판단했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지금까지 @section, enum raw value, 정수 제네릭 인자는 모두 &quot;사람이 직접 계산해서 bare literal로 옮겨 적어야 하는&quot; 동일한 제약을 공유하고 있었어요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Literal Expression은 이 세 컨텍스트에 산술&amp;middot;비트&amp;middot;단항 연산과 변수 참조를 허용함으로써, &lt;b&gt;코드에 값의 의도를 직접 드러낼 수 있게&lt;/b&gt; 해줍니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그러면서도 컴파일 타임에 완전히 폴딩되기 때문에 &lt;b&gt;ABI나 런타임에는 전혀 영향이 없다&lt;/b&gt;는 점이 인상적이에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;매직 넘버 대신 16 * pageSize, 1 &amp;lt;&amp;lt; 2처럼 의미가 드러나는 코드를 쓸 수 있게 되는, 작지만 가독성 측면에서 정말 실용적인 변화라고 생각합니다  &lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1781988395150&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;swift-evolution/proposals/0531-literal-expressions.md at main &amp;middot; swiftlang/swift-evolution&quot; data-og-description=&quot;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0531-literal-expressions.md&quot; data-og-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0531-literal-expressions.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/0UhV2/dJMb8Z3AXeo/v7TUtKx5kSp4bCqelXq6N0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/b44HlR/dJMb8SpRw8k/ZX8FBm07fpIV7NKXxrn5cK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0531-literal-expressions.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0531-literal-expressions.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/0UhV2/dJMb8Z3AXeo/v7TUtKx5kSp4bCqelXq6N0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/b44HlR/dJMb8SpRw8k/ZX8FBm07fpIV7NKXxrn5cK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;swift-evolution/proposals/0531-literal-expressions.md at main &amp;middot; swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Swift</category>
      <category>ios</category>
      <category>Literal Expressions</category>
      <category>SE-0531</category>
      <category>SWIFT</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/624</guid>
      <comments>https://green1229.tistory.com/624#entry624comment</comments>
      <pubDate>Sun, 21 Jun 2026 05:47:30 +0900</pubDate>
    </item>
    <item>
      <title>[SE-0530] Async Result Support</title>
      <link>https://green1229.tistory.com/623</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 포스팅에서는&lt;span style=&quot;background-color: #9feec3;&quot;&gt; &lt;b&gt;SE-0530 &amp;mdash; Result 타입의 async 이니셜라이저 추가&lt;/b&gt;&lt;/span&gt;에 대해 정리해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;123123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmAgh6/dJMcaiQ6Tiq/gC2NYadyZTQo9N7yS0b88k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmAgh6/dJMcaiQ6Tiq/gC2NYadyZTQo9N7yS0b88k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmAgh6/dJMcaiQ6Tiq/gC2NYadyZTQo9N7yS0b88k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmAgh6%2FdJMcaiQ6Tiq%2FgC2NYadyZTQo9N7yS0b88k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;123123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposal:&lt;/b&gt; SE-0530&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Authors:&lt;/b&gt; Konrad 'ktoso' Malawski, Matt Massicotte&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Review Manager:&lt;/b&gt; Doug Gregor&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Status:&lt;/b&gt; Implemented (Swift 6.4)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift의 &lt;code&gt;Result&lt;/code&gt; 타입은 throwing 코드를 다룰 때 굉장히 유용한 도구입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;기존의 &lt;code&gt;Result.init(catching:)&lt;/code&gt;은 throwing 클로저를 &lt;code&gt;Result&lt;/code&gt; 인스턴스로 변환해주는 편리한 이니셜라이저예요.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;isbl&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// 기존: 동기 버전은 있음
let result = Result { try syncWork() }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그런데 &lt;b&gt;async 버전이 없었어요.&lt;/b&gt; 비동기 작업에서 동일한 패턴을 쓰려면 매번 직접 구현해야 했거든요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// 지금까지의 불편한 방식 &amp;mdash; 코드베이스마다 중복 구현
let result: Result&amp;lt;Data, any Error&amp;gt;
do {
  result = .success(try await asyncWork())
} catch {
  result = .failure(error)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;어렵진 않지만, 유용성 때문에 많은 코드베이스에서 수동으로 중복 구현되고 있었거든요. 표준 라이브러리가 제공해야 마땅한 패턴이에요!&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposed Solution&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;Result.init(catching:)&lt;/code&gt;의 &lt;b&gt;async 오버로드&lt;/b&gt;를 추가합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이를 통해 아래처럼 간결하게 쓸 수 있게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;isbl&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;let result = await Result {
  try await asyncWork()
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Detailed Design&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제안하는 API 변경 사항은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cs&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;extension Result where Success: ~Copyable {
  /// Creates a new result by evaluating a throwing closure,
  /// capturing the returned value as a success,
  /// or any thrown error as a failure.
  ///
  /// - Parameter body: A potentially throwing asynchronous closure to evaluate.
  @_alwaysEmitIntoClient
  public nonisolated(nonsending) init(
    catching body: nonisolated(nonsending) () async throws(Failure) -&amp;gt; Success
  ) async {
    do {
      self = .success(try await body())
    } catch {
      self = .failure(error)
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;주요 포인트를 살펴볼게요~!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Success: ~Copyable&lt;/b&gt; &amp;mdash; noncopyable 타입도 Success로 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;throws(Failure)&lt;/b&gt; &amp;mdash; SE-0413의 typed throws를 활용해 Failure 타입을 정확하게 표현합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;nonisolated(nonsending)&lt;/b&gt; &amp;mdash; actor isolation 없이 호출 가능하며, 클로저의 반환값을 안전하게 전달합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;@_alwaysEmitIntoClient&lt;/b&gt; &amp;mdash; 이니셜라이저가 클라이언트 바이너리에 직접 인라인되어 backdeployment가 가능합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Source Compatibility / ABI&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 변경은 &lt;b&gt;순수 additive 변경&lt;/b&gt;으로, 기존 코드에 영향을 주지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;@_alwaysEmitIntoClient&lt;/code&gt;로 표시되어 &lt;b&gt;이전 Swift 버전으로의 backdeployment가 가능&lt;/b&gt;합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;아주 작은 변경이지만, 비동기 코드에서 &lt;code&gt;Result&lt;/code&gt;를 다루는 패턴이 훨씬 간결해집니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;많은 코드베이스에서 반복적으로 직접 구현해왔던 보일러플레이트를 표준 라이브러리가 흡수해주는 변경이에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;Result { try await asyncWork() }&lt;/code&gt; &amp;mdash; 동기 버전과 완전히 동일한 패턴으로 async 작업을 처리할 수 있게 되어, 코드의 일관성도 높아질 것 같습니다  &lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1780812636842&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;swift-evolution/proposals/0530-async-result-support.md at main &amp;middot; swiftlang/swift-evolution&quot; data-og-description=&quot;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0530-async-result-support.md&quot; data-og-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0530-async-result-support.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3kbCZ/dJMb82MKWkv/xRqTaEcIAznwcRs4z0TofK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cPkFaM/dJMb88GcMXS/gBcLJRXCDvKS7fqKlH8hbk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0530-async-result-support.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0530-async-result-support.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3kbCZ/dJMb82MKWkv/xRqTaEcIAznwcRs4z0TofK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cPkFaM/dJMb88GcMXS/gBcLJRXCDvKS7fqKlH8hbk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;swift-evolution/proposals/0530-async-result-support.md at main &amp;middot; swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Swift</category>
      <category>Async Result</category>
      <category>SE-0530</category>
      <category>SWIFT</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/623</guid>
      <comments>https://green1229.tistory.com/623#entry623comment</comments>
      <pubDate>Sun, 7 Jun 2026 15:09:13 +0900</pubDate>
    </item>
    <item>
      <title>[SE-0528] Continuation &amp;mdash; Safe and Performant Async Continuations</title>
      <link>https://green1229.tistory.com/622</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 포스팅에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;SE-0528 &amp;mdash; 안전하고 성능 좋은 Async Continuation, Continuation 타입 도입&lt;/b&gt;&lt;/span&gt;에 대해 정리해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;123213.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RoShb/dJMcajvD1RK/pZlKfBxBCKYLz597JeyTL0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RoShb/dJMcajvD1RK/pZlKfBxBCKYLz597JeyTL0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RoShb/dJMcajvD1RK/pZlKfBxBCKYLz597JeyTL0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRoShb%2FdJMcajvD1RK%2FpZlKfBxBCKYLz597JeyTL0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;123213.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposal:&lt;/b&gt; SE-0528&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Authors:&lt;/b&gt; Fabian Fett, Konrad Malawski&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Review Manager:&lt;/b&gt; Joe Groff&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Status:&lt;/b&gt; Accepted with revisions&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Continuation은 콜백 기반 API를 Swift Structured Concurrency로 연결하는 핵심 메커니즘입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그런데 현재 개발자는 두 가지 옵션 중 하나를 골라야 하는 불편한 선택을 강요받고 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;UnsafeContinuation&lt;/b&gt; &amp;mdash; 오버헤드는 없지만, 두 번 resume하면 undefined behavior, resume을 빠뜨리면 조용히 task가 영원히 leak됩니다  &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;CheckedContinuation&lt;/b&gt; &amp;mdash; 런타임 bookkeeping으로 실수를 감지하지만, allocation과 atomic 연산 오버헤드가 발생합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Continuation은 정확히 한 번만 resume해야 하는 &quot;use-exactly-once&quot; 값입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이건 move-only 타입이 강제할 수 있는 계약이에요. 타입 시스템이 이 문제를 해결해야 합니다!&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposed Solution&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;Continuation&amp;lt;Success: ~Copyable, Failure: Error&amp;gt;&lt;/code&gt;, 즉 &lt;code&gt;~Copyable&lt;/code&gt; struct를 도입합니다. 세 가지 메커니즘으로 올바른 사용을 강제합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Move-only semantics (~Copyable)&lt;/b&gt; &amp;mdash; continuation을 복사할 수 없으므로, 두 곳에서 resume하는 것이 불가능합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;consuming 메서드&lt;/b&gt; &amp;mdash; 모든 resume 메서드는 self를 consume해 두 번째 호출은 컴파일 에러가 됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;deinit 트랩 + discard self&lt;/b&gt; &amp;mdash; resume 없이 continuation이 drop되면 fatalError. 정상 resume 시엔 discard self로 deinit을 억제해 오버헤드가 없어요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Double-resume &amp;mdash; 컴파일 에러로 해결!&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;actor LegacyBridge {
  func complete(with value: String) {
    if let continuation {
      continuation.resume(returning: value) // ✅ consumes continuation
      continuation.resume(returning: value) // ❌ compile error:
                                            // 'continuation' used after consuming use
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Missing-resume &amp;mdash; 런타임 트랩으로 포착!&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;actor LegacyBridge {
  func cancel() {
    // Bug: resume 없이 continuation을 지워버림
    self.continuation = nil //   runtime trap: &quot;This continuation was dropped.&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Detailed Design&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Continuation 타입 정의&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;@frozen
public struct Continuation&amp;lt;Success: ~Copyable, Failure: Error&amp;gt;: ~Copyable, Sendable {

  deinit {
    fatalError(&quot;The continuation was dropped without resuming.&quot;)
  }

  @inlinable
  public consuming func resume(returning value: consuming sending Success) { ... }

  @inlinable
  public consuming func resume(throwing error: Failure) { ... }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Sendable&lt;/b&gt; &amp;mdash; 다른 task/thread에서 resume할 수 있도록 isolation boundary를 넘을 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;consuming&lt;/b&gt; &amp;mdash; 각 resume 메서드가 self를 consume해 이후 사용이 불가능해집니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;sending Success&lt;/b&gt; &amp;mdash; non-Sendable 값을 async task에 안전하게 전달할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;consuming Success&lt;/b&gt; &amp;mdash; noncopyable 타입도 값으로 전달할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;discard self&lt;/b&gt; &amp;mdash; 정상 resume 시 deinit을 억제해 오버헤드가 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;withContinuation &amp;mdash; of: 와 throwing: 파라미터&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;haskell&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// Before: 클로저 파라미터에 타입 어노테이션 필요
let data = await withCheckedContinuation { (continuation: UnsafeContinuation&amp;lt;Data, Never&amp;gt;) in
  bridge.store(continuation)
}

// After: 호출부에서 타입이 명확하게 보임
let data = await withContinuation(of: Data.self) { continuation in
  bridge.store(continuation)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;throwing:&lt;/code&gt; 파라미터는 SE-0413(typed throws)를 활용해 세 가지 경우를 하나의 함수로 통합합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// Non-throwing
let data = await withContinuation(of: Data.self) { continuation in ... }

// Typed throwing
let data = try await withContinuation(of: Data.self, throwing: NetworkError.self) { continuation in ... }

// Untyped throwing
let data = try await withContinuation(of: Data.self, throwing: (any Error).self) { continuation in ... }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;CheckedContinuation으로 변환하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;콜백이 여러 개인 경우처럼 noncopyable Continuation을 사용할 수 없는 경우엔 CheckedContinuation으로 변환해 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;try await withContinuation(of: Int.self, throwing: (any Error).self) { c in
  let checked = CheckedContinuation(c)
  someLib.onSuccess { checked.resume(returning: $0) } // ✅
  someLib.onFailure  { checked.resume(throwing: $0)  } // ✅
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 때문에 &lt;code&gt;CheckedContinuation&lt;/code&gt;과 &lt;code&gt;UnsafeContinuation&lt;/code&gt;은 &lt;b&gt;deprecated되지 않고 계속 유지&lt;/b&gt;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;동작 비교표&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;width: 100%; border-collapse: collapse; font-size: 13px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;시나리오&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;UnsafeContinuation&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;CheckedContinuation&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Continuation&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;정상 resume&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;✅ 동작&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;✅ 동작&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;✅ 동작&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Double resume&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;⚠️ Undefined Behavior&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;  Runtime trap&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;❌ 컴파일 에러&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Missing resume&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;  Silent hang&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;⚠️ Runtime warning&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;  Runtime trap&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;런타임 오버헤드&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;없음&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;allocation + atomic&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;없음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Implications on Adoption&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;table style=&quot;width: 100%; border-collapse: collapse; font-size: 13px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Before&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;After&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;withCheckedContinuation { &amp;hellip; }&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;withContinuation(of: T.self) { &amp;hellip; }&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;withCheckedThrowingContinuation { &amp;hellip; }&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;withContinuation(of: T.self, throwing: (any Error).self) { &amp;hellip; }&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;CheckedContinuation&amp;lt;T, E&amp;gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Continuation&amp;lt;T, E&amp;gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;단, &lt;code&gt;Continuation&lt;/code&gt;은 &lt;code&gt;~Copyable&lt;/code&gt;이기 때문에, 클로저 캡처처럼 continuation을 암묵적으로 복사하는 패턴은 컴파일 에러가 됩니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 경우엔 기존 &lt;code&gt;Checked/UnsafeContinuation&lt;/code&gt;을 사용해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Source Compatibility / ABI&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 변경은 &lt;b&gt;순수 additive 변경&lt;/b&gt;으로, 기존 코드에 영향을 주지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;withContinuation&lt;/code&gt;과 &lt;code&gt;Continuation&lt;/code&gt;이라는 이름은 기존 표준 라이브러리 API와 충돌하지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ABI 변경도 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Future Directions&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;~Discardable 프로토콜 도입&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;현재는 continuation이 drop될 때 런타임 트랩에 의존하고 있지만, &lt;code&gt;~Copyable&lt;/code&gt; 타입을 위한 새로운 모드인 &lt;code&gt;~Discardable&lt;/code&gt;을 도입해 &quot;반드시 명시적으로 consume해야 함&quot;을 컴파일러가 강제하게 할 수 있어요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 되면 런타임 트랩마저 컴파일 에러로 격상될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;드디어 &lt;b&gt;오버헤드 없이 안전한 Continuation&lt;/b&gt;이 생겼습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;기존에는 안전성(CheckedContinuation)과 성능(UnsafeContinuation) 사이에서 트레이드오프를 강요받았는데, move-only 타입의 강점을 활용해 double-resume은 컴파일 에러로, missing-resume은 런타임 트랩으로 잡아주면서 &lt;b&gt;오버헤드는 UnsafeContinuation과 동일하게 유지&lt;/b&gt;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift 타입 시스템의 힘으로 콜백 브리징의 고질적인 버그 두 가지를 완전히 해결한 우아한 변경이라고 생각합니다  &lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1780107743939&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;swift-evolution/proposals/0528-noncopyable-continuation.md at main &amp;middot; swiftlang/swift-evolution&quot; data-og-description=&quot;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0528-noncopyable-continuation.md&quot; data-og-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0528-noncopyable-continuation.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/z0YHF/dJMb9lMihTX/AL4VKHNgE0oMthmaFtMx81/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/N18xg/dJMb9dHuZTO/kCumznq6mm76JnJKZ7buXk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0528-noncopyable-continuation.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0528-noncopyable-continuation.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/z0YHF/dJMb9lMihTX/AL4VKHNgE0oMthmaFtMx81/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/N18xg/dJMb9dHuZTO/kCumznq6mm76JnJKZ7buXk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;swift-evolution/proposals/0528-noncopyable-continuation.md at main &amp;middot; swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Swift</category>
      <category>Continuation</category>
      <category>ios</category>
      <category>SE-0528</category>
      <category>SWIFT</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/622</guid>
      <comments>https://green1229.tistory.com/622#entry622comment</comments>
      <pubDate>Sat, 30 May 2026 11:19:40 +0900</pubDate>
    </item>
    <item>
      <title>[SE-0522] Source-Level Control Over Compiler Warnings</title>
      <link>https://green1229.tistory.com/621</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 포스팅에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;SE-0522 &amp;mdash; 소스 레벨에서의 컴파일러 경고 제어&lt;/b&gt;&lt;/span&gt;에 대해 정리해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;123123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biDDgS/dJMcaarThnr/T02voEgk3U5Hk4SnJmkkck/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biDDgS/dJMcaarThnr/T02voEgk3U5Hk4SnJmkkck/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biDDgS/dJMcaarThnr/T02voEgk3U5Hk4SnJmkkck/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiDDgS%2FdJMcaarThnr%2FT02voEgk3U5Hk4SnJmkkck%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;123123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposal:&lt;/b&gt; SE-0522&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Authors:&lt;/b&gt; Artem Chikin, Doug Gregor, Holly Borla&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Review Manager:&lt;/b&gt; Tony Allevato&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Status:&lt;/b&gt; Accepted&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;SE-0443에서는 커맨드라인 플래그로 컴파일러 경고를 제어할 수 있게 되었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;예를 들어 &lt;code&gt;-Werror DeprecatedDeclaration&lt;/code&gt;을 사용하면 Deprecated 경고를 에러로 격상시킬 수 있죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;하지만 이 방식은 &lt;b&gt;모듈 전체&lt;/b&gt;에 적용되는 블런트한 수단이에요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;특정 선언에서만 예외를 두고 싶은 경우에는 대응할 방법이 없었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;awk&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// 모듈 전체에 -Werror DeprecatedDeclaration 적용 중
func bridgeToLegacySystem() {
  oldAPI() //   error: 'oldAPI()' is deprecated [#Deprecated]
}
// 이 함수만 warning으로 낮추고 싶어도 방법이 없었어요&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;마이그레이션 중인 코드베이스, 레거시 호환성 유지, strict 언어 모드의 점진적 도입 등 현실에서 &quot;&lt;b&gt;딱 이 선언만 예외&quot;가 필요한 순간은 생각보다 많거든요!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposed Solution&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;새로운 선언 어트리뷰트 &lt;code&gt;@diagnose&lt;/code&gt;를 도입합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;어노테이션된 선언의 &lt;b&gt;렉시컬 스코프 내&lt;/b&gt;에서 특정 diagnostic group의 경고 동작을 &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt;, &lt;code&gt;ignored&lt;/code&gt; 세 가지 중 하나로 제어할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;기본 문법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;@diagnose(group-identifier, as: error | warning | ignored)
@diagnose(group-identifier, as: behavior, reason: &quot;이유&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;동작 예시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// 모듈 전체: -Werror DeprecatedDeclaration 적용 중

func normalFunction() {
  oldAPI() //   error
}

@diagnose(DeprecatedDeclaration, as: warning,
           reason: &quot;Must maintain compatibility until end of release cycle&quot;)
func bridgeToLegacySystem() {
  oldAPI() //   warning: 'oldAPI()' is deprecated [#Deprecated]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;ignored&lt;/code&gt;로 지정하면 해당 스코프에서 완전히 경고를 억제할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;@diagnose(UnsafeImportedAPI, as: warning)
struct LegacyFormatReader {
  func read(_ data: UnsafeRawPointer, _ count: Int) -&amp;gt; Header {
    c_read_bundle(data, count) //   warning
  }

  @diagnose(UnsafeImportedAPI, as: ignored, reason: &quot;input is validated upstream&quot;)
  func readTrustedInput(_ data: UnsafeRawPointer, _ count: Int) -&amp;gt; Header {
    c_read_bundle(data, count) // 진단 없음
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;서브그룹에도 개별적으로 적용이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// UnsafeImportedOwnership은 UnsafeImportedAPI의 서브그룹
// 모듈 전체: -Werror UnsafeImportedAPI

@diagnose(UnsafeImportedOwnership, as: warning)
func createSession(_ ctx: OpaquePointer) -&amp;gt; Session {
  let session = c_create_session(ctx)
  //   warning: cannot infer ownership ... [#UnsafeImportedOwnership]

  c_bind_session(session, nil)
  //   error: call to imported function ... [#UnsafeImportedAPI]
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Detailed Design&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;적용 가능한 선언 종류&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;@diagnose&lt;/code&gt;는 func, struct, class, enum, actor, protocol, extension, init, deinit, subscript, macro, typealias, associatedtype, get/set, willSet/didSet, import, enum case 등 대부분의 선언에 적용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;@diagnose(DiagGroupID, as: ignored)
import bar

@diagnose(DiagGroupID, as: ignored, reason: &quot;Proposal Example&quot;)
func foo() { ... }

struct Foo {
  var property: Int {
    @diagnose(DiagGroupID, as: ignored)
    get { ... }
    @diagnose(DiagGroupID, as: ignored)
    set { ... }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;여러 @diagnose 어트리뷰트 &amp;mdash; 순서가 중요합니다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;동일한 선언에 여러 &lt;code&gt;@diagnose&lt;/code&gt;를 적용할 경우 &lt;b&gt;마지막(렉시컬 순서상 가장 아래)에 있는 어트리뷰트가 우선&lt;/b&gt;합니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;less&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;@diagnose(DiagGroupID, as: error)
@diagnose(DiagGroupID, as: warning) // 이 쪽이 최종 적용됨
public func foo() { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Swift 어트리뷰트는 일반적으로 순서 무관하지만, @diagnose는 SE-0443의 커맨드라인 플래그 동작과 일관성을 맞추기 위해 순서가 중요합니다!&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;-suppress-warnings와의 관계&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;-suppress-warnings&lt;/code&gt; 플래그가 적용된 상태에서는 &lt;code&gt;@diagnose&lt;/code&gt;가 완전히 무시됩니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;as: error&lt;/code&gt;를 지정해도 에러로 격상되지 않아요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이는 SE-0480에서 SwiftPM이 외부 패키지 의존성 빌드 시 경고 관련 플래그를 &lt;code&gt;-suppress-warnings&lt;/code&gt;로 대체하는 방식과의 일관성을 위한 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;매크로와의 상호작용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;@diagnose&lt;/code&gt;가 적용된 스코프 내에서 매크로가 코드를 생성하면, 그 생성된 코드에도 어트리뷰트의 효과가 적용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;또한 매크로 작성자가 &lt;b&gt;매크로 확장 코드 안에 직접 &lt;code&gt;@diagnose&lt;/code&gt;를 생성&lt;/b&gt;할 수도 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;autoit&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// 매크로 확장 결과물에 @diagnose가 포함될 수 있어요
@diagnose(DeprecatedDeclaration, as: error)
public func endpoint() -&amp;gt; UserProvidedType {
  //   error: 'UserProvidedType' is deprecated [#DeprecatedDeclaration]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;단, 어트리뷰트가 적용된 선언에 peer 매크로가 붙어 있는 경우, &lt;code&gt;@diagnose&lt;/code&gt;의 효과는 peer로 생성된 독립 선언에는 전파되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Source Compatibility / ABI&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 변경은 &lt;b&gt;순수 additive 변경&lt;/b&gt;으로 기존 소스 호환성에 영향이 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ABI에도 영향이 없으며, 텍스트 모듈 인터페이스에도 방출되지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;배포 제약 없이 자유롭게 도입하거나 제거할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Alternatives Considered&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Region-based #pragma 스타일 지시문&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Clang 등 C계열 컴파일러처럼 임의 코드 영역에 &lt;code&gt;#pragma clang diagnostic push/pop&lt;/code&gt;을 사용하는 방식도 고려되었어요. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;하지만 Swift는 메타데이터와 동작을 선언에 귀속시키는 방식을 선호하고, 영역의 끝을 수동으로 관리해야 한다는 점이 복잡한 버그로 이어질 수 있어 채택되지 않았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;매크로 생성 코드에서 @diagnose 금지하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;모든 경고 제어가 개발자 소스 코드에서 명시적으로 보이도록 매크로 확장에서 &lt;code&gt;@diagnose&lt;/code&gt; 생성을 금지하는 방법도 고려되었지만, 매크로 작성자가 자신이 생성하는 코드에 대한 진단 정책을 표현할 수 없게 되므로 허용하는 방향으로 결정되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;-suppress-warnings 하에서도 as: error 적용하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;무조건적인 소스 레벨 에러 격상을 위해 &lt;code&gt;-suppress-warnings&lt;/code&gt; 하에서도 &lt;code&gt;as: error&lt;/code&gt;를 적용하는 방법도 고려되었지만, SE-0443 및 SE-0480과의 일관성 유지를 위해 채택되지 않았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Future Directions&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;로컬 렉시컬 스코프 제어&lt;/b&gt; &amp;mdash; &lt;code&gt;do {}&lt;/code&gt; 블록처럼 선언이 아닌 임의 스코프에도 적용하는 방향&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;클로저 표현식&lt;/b&gt; &amp;mdash; 특정 클로저 body의 경고 동작 제어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;파일 스코프 제어&lt;/b&gt; &amp;mdash; &lt;code&gt;using @diagnose(...)&lt;/code&gt; 형태의 파일 범위 제어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;서드파티 툴 통합&lt;/b&gt; &amp;mdash; &lt;code&gt;@diagnose(rule, from: SwiftLint, as: ignored)&lt;/code&gt; 같은 형태로 린터 등과의 통합&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;커맨드라인 플래그로만 가능했던 경고 제어를 &lt;b&gt;소스 레벨의 선언 단위로 세밀하게&lt;/b&gt; 다룰 수 있게 해주는 실용적인 변경입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;마이그레이션 중인 코드베이스, 레거시 호환성 유지, strict 언어 모드의 점진적 도입 등 현실적인 시나리오에서 개발자가 &lt;b&gt;예외의 의도를 코드에 명확하게 문서화&lt;/b&gt;할 수 있게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Swift가 더 엄격한 언어 모드와 정적 분석을 강화해가는 흐름 속에서, &lt;code&gt;@diagnose&lt;/code&gt;는 그 여정을 훨씬 유연하게 해줄 도구라고 생각합니다  &lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1779493468301&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;swift-evolution/proposals/0522-source-warning-control.md at main &amp;middot; swiftlang/swift-evolution&quot; data-og-description=&quot;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0522-source-warning-control.md&quot; data-og-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0522-source-warning-control.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/KThi1/dJMb9aKK4Ud/IahxrCuvGxPnOhVkDYa8Yk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ti5ct/dJMb87N2EQF/wYeK8dRAoKoh3JX2suE4Sk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0522-source-warning-control.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0522-source-warning-control.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/KThi1/dJMb9aKK4Ud/IahxrCuvGxPnOhVkDYa8Yk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ti5ct/dJMb87N2EQF/wYeK8dRAoKoh3JX2suE4Sk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;swift-evolution/proposals/0522-source-warning-control.md at main &amp;middot; swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Swift</category>
      <category>ios</category>
      <category>SE-0522</category>
      <category>SWIFT</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/621</guid>
      <comments>https://green1229.tistory.com/621#entry621comment</comments>
      <pubDate>Sat, 23 May 2026 08:45:27 +0900</pubDate>
    </item>
    <item>
      <title>[SE-0523] Hashable conformance for UnownedTaskExecutor</title>
      <link>https://green1229.tistory.com/620</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;안녕하세요. &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;그린&lt;/b&gt;&lt;/span&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 포스팅에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;SE-0523 &amp;mdash; UnownedTaskExecutor의 Hashable 채택&lt;/b&gt;&lt;/span&gt;에 대해 정리해보겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;123123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chnXEU/dJMcadopJaQ/4XUWgRtY6Cknp9f56gCpbK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chnXEU/dJMcadopJaQ/4XUWgRtY6Cknp9f56gCpbK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chnXEU/dJMcadopJaQ/4XUWgRtY6Cknp9f56gCpbK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchnXEU%2FdJMcadopJaQ%2F4XUWgRtY6Cknp9f56gCpbK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;400&quot; data-filename=&quot;123123.001.jpeg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Proposal:&lt;/b&gt; SE-0523&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Authors:&lt;/b&gt; Fabian Fett, Konrad Malawski&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Review Manager:&lt;/b&gt; John McCall&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Status:&lt;/b&gt; Implemented (Swift 6.4)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;SE-0417에서 도입된 task executor preferences는 현재 실행 중인 task의 &lt;code&gt;unownedTaskExecutor&lt;/code&gt;를 노출해, 성능에 민감한 코드가 executor 기반으로 스케줄링 결정을 내릴 수 있게 해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;UnownedTaskExecutor&lt;/code&gt;는 이미 &lt;code&gt;Equatable&lt;/code&gt;을 채택하고 있어요. &lt;br /&gt;그런데 &lt;code&gt;Hashable&lt;/code&gt;이 없다 보니, executor를 기준으로 리소스를 인덱싱해야 하는 경우에 불편함이 생겼습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;대표적인 사례가 &lt;b&gt;커넥션 풀링&lt;/b&gt;입니다.&lt;br /&gt;&lt;code&gt;ConnectionPool&lt;/code&gt;이 여러 executor에 걸쳐 커넥션을 관리할 때, task의 executor에 이미 연결된 커넥션을 우선적으로 반환하면 &lt;b&gt;불필요한 컨텍스트 스위치를 줄일 수 있거든요  &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Hashable이 없으면 executor를 찾기 위해 매번 선형 탐색을 해야 합니다  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Before &amp;mdash; O(n) 선형 탐색&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// Today: O(n) linear search
func pickConnection(preferring executor: UnownedTaskExecutor) -&amp;gt; Connection {
    for (e, connection) in executorConnectionList {
        if e == executor { return connection }
    }
    return executorConnectionList.first!.connection
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;&lt;br /&gt;After &amp;mdash; O(1) 딕셔너리 조회&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;// With Hashable: O(1) dictionary lookup
func pickConnection(preferring executor: UnownedTaskExecutor) -&amp;gt; Connection {
    if let connection = connectionsByExecutor[executor] {
        return connection
    }
    return connectionsByExecutor.values.first!
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 패턴은 커넥션 풀링뿐만 아니라 executor identity를 기준으로 &lt;b&gt;리소스, 캐시, 스케줄링 메타데이터를 인덱싱하는 모든 시스템에 적용&lt;/b&gt;될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Detailed Design&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;UnownedTaskExecutor&lt;/code&gt;는 &lt;code&gt;Builtin.Executor&lt;/code&gt; 값을 감싸는 struct입니다. &lt;br /&gt;이미 기저 executor 참조의 &lt;b&gt;identity&lt;/b&gt;를 기반으로 &lt;code&gt;Equatable&lt;/code&gt; 채택이 되어 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;Hashable&lt;/code&gt; 채택도 동일한 identity 값을 해싱하므로, 기존 equality 시맨틱과 &lt;b&gt;일관성을 완전히 유지&lt;/b&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;swift&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;extension UnownedTaskExecutor: Hashable {}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;API 변경은 이것이 전부입니다. 딱 한 줄이에요  &lt;/span&gt;&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Source Compatibility / ABI&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이번 변경은 &lt;b&gt;순수 additive 변경&lt;/b&gt;으로, 기존 코드는 변경 없이 그대로 컴파일됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;Equatable&lt;/code&gt;을 채택한 타입에 &lt;code&gt;Hashable&lt;/code&gt;을 추가하는 것은 소스 호환성을 깨지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;프로토콜 채택 추가는 additive ABI 변경이며, 기존 ABI 서피스를 수정하지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Alternatives Considered&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;아무것도 하지 않기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;아무것도 하지 않으면, 개발자가 직접 &lt;code&gt;Hashable&lt;/code&gt; 채택을 구현해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background: #1e1e1e; color: #d4d4d4; padding: 16px; border-radius: 8px; font-size: 13px; overflow-x: auto;&quot;&gt;&lt;code&gt;extension UnownedTaskExecutor: Hashable {
  @inlinable
  public func hash(into hasher: inout Hasher) {
    let (ident, impl) = unsafeBitCast(self, to: (Int, Int).self)
    hasher.combine(ident)
    hasher.combine(impl)
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;br /&gt;&lt;code&gt;unsafeBitCast&lt;/code&gt;를 직접 사용해야 한다는 점에서 불필요하게 위험하고 번거롭습니다. 표준 라이브러리 차원에서 제공하는 것이 당연히 올바른 방향이라고 생각합니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;아주 작은 변경이지만, &lt;b&gt;굉장히 자연스러운 확장&lt;/b&gt;입니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;Equatable&lt;/code&gt;을 채택하고 있는 타입이라면 &lt;code&gt;Hashable&lt;/code&gt;도 당연히 지원해야 한다는 Swift의 설계 철학에 맞게, &lt;code&gt;UnownedTaskExecutor&lt;/code&gt;도 이제 딕셔너리 키와 Set으로 자유롭게 활용할 수 있게 됩니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;executor 기반으로 리소스를 관리하는 코드를 작성하고 계신 분들께 특히 반가운 소식일 것 같습니다  &lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1778784735249&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;swift-evolution/proposals/0523-hashable-unownedtask-executor.md at main &amp;middot; swiftlang/swift-evolution&quot; data-og-description=&quot;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0523-hashable-unownedtask-executor.md&quot; data-og-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0523-hashable-unownedtask-executor.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bFo2Ef/dJMb86O6MRN/Xbx3QejrczjXFYwm2EyKO0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cdAawY/dJMb88F90tX/1z39Br2VC2aqKHkZd6lelk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0523-hashable-unownedtask-executor.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/swiftlang/swift-evolution/blob/main/proposals/0523-hashable-unownedtask-executor.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bFo2Ef/dJMb86O6MRN/Xbx3QejrczjXFYwm2EyKO0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cdAawY/dJMb88F90tX/1z39Br2VC2aqKHkZd6lelk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;swift-evolution/proposals/0523-hashable-unownedtask-executor.md at main &amp;middot; swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Swift</category>
      <category>hashable</category>
      <category>ios</category>
      <category>SE-0523</category>
      <category>SWIFT</category>
      <category>UnownedTaskExecutor</category>
      <author>GREEN.1229</author>
      <guid isPermaLink="true">https://green1229.tistory.com/620</guid>
      <comments>https://green1229.tistory.com/620#entry620comment</comments>
      <pubDate>Fri, 15 May 2026 03:53:25 +0900</pubDate>
    </item>
  </channel>
</rss>