<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발자 찬히히</title>
    <link>https://chanhhh.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 29 Jun 2026 05:46:29 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>찬히히</managingEditor>
    <image>
      <title>개발자 찬히히</title>
      <url>https://tistory1.daumcdn.net/tistory/3981372/attach/ad57a022046a455f8c2009339f076836</url>
      <link>https://chanhhh.tistory.com</link>
    </image>
    <item>
      <title>[WWDC 2026] 요약 및 정리, 그리고 iOS 개발자로서의 생각</title>
      <link>https://chanhhh.tistory.com/363</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;들어가기 앞서&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번 WWDC 2026은 개인적으로 &amp;ldquo;애플이 드디어 본격적으로 움직이기 시작했구나&amp;rdquo;라는 생각이 들었던 행사였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;최근 들어 OpenAI, Google, Anthropic, Meta 등 &amp;lsquo;M7&amp;rsquo; 기업들의 AI 경쟁을 지켜보면서 AI 버블론과 반도체 거품론에 대한 다양한 의견들도 함께 접하게 되었습니다. 그 과정에서 애플은 유독 조금 다른 길을 걷고 있다는 느낌을 받았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;물론 애플은 여전히 강력한 생태계와 하드웨어, 그리고 충성도 높은 사용자 기반을 가진 기업입니다. 그렇기에 AI 경쟁이 과열되는 와중에도 &amp;ldquo;애플은 애플만의 방식으로 가겠지&amp;rdquo;라는 생각이 들었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;하지만 한편으로는 이런 의문도 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;지금 전 세계 기술 산업이 AI를 중심으로 재편되고 있는데, 애플은 왜 이렇게 조용할까?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;실제로 지난해 WWDC를 보고 난 뒤에는 Apple Intelligence가 기대에 비해 다소 제한적으로 느껴졌고, Siri 역시 경쟁사 서비스들과 비교했을 때 아쉬움이 남았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;저 역시 비슷한 고민을 하고 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;최근 업무를 하면서 Xcode를 사실상 빌드와 실행을 위한 도구로만 사용하고 있었고, 실제 개발은 Codex, Claude Code 같은 AI 도구의 도움을 받는 시간이 점점 늘어나고 있었습니다. 문득 돌아보니 개발 환경 자체가 빠르게 변하고 있는데, 애플은 그 변화의 중심에 서 있지 못한 것처럼 보였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그런 의미에서 이번 WWDC는 꽤 인상적이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;애플이 처음으로 AI를 기능 하나가 아니라 플랫폼 전체의 전략으로 다루기 시작했다는 느낌을 받았기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;가장 큰 발표는 Google Gemini를 포함한 외부 LLM과의 연동을 강화한 Siri였고, 그 외에도 iOS 27을 비롯한 6개의 운영체제 전반에 Apple Intelligence가 깊게 통합되었습니다. 또한 개발자들을 위한 AI 기반 개발 도구와 플랫폼 지원 역시 대폭 강화되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번 글에서는 WWDC 2026에서 발표된 주요 내용을 간단히 정리하고, iOS 개발자의 관점에서 어떤 의미가 있었는지 이야기해보려고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;개발자 도구(Xcode, AI Coding Assistant, Swift 개발 환경 등)에 대한 내용은 분량이 길어질 것 같아 다음 포스트에서 따로 다뤄보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;1552&quot; data-origin-height=&quot;1364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m628K/dJMcagTs1GW/GIVW5uUDWU8YMajz8Lfds1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m628K/dJMcagTs1GW/GIVW5uUDWU8YMajz8Lfds1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m628K/dJMcagTs1GW/GIVW5uUDWU8YMajz8Lfds1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm628K%2FdJMcagTs1GW%2FGIVW5uUDWU8YMajz8Lfds1%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;449&quot; height=&quot;395&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;1364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;WWDC 2026 핵심 요약&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. Siri가 드디어 AI가 되었다&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번 WWDC의 주인공은 단연 Siri였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Apple은 단순 음성 비서 수준에 머물러 있던 기존 Siri를 완전히 재구성해 &amp;ldquo;Siri AI&amp;rdquo;라는 새로운 형태로 공개했습니다. 가장 큰 특징은 Google Gemini 기반 모델을 활용해 기존 Siri의 한계를 극복했다는 점입니다. &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;기존 Siri가 &amp;ldquo;명령 수행 도구&amp;rdquo;에 가까웠다면, 새로운 Siri는 ChatGPT나 Gemini처럼 대화를 이어가고 맥락을 이해하는 방향으로 발전했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&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: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;화면에 보이는 내용을 이해하는 On-Screen Awareness&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;앱 간 작업을 연결하는 Multi-Step Action&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;개인 정보와 사용 이력을 활용한 Context 이해&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;별도의 Siri AI 앱 제공&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이미지와 카메라 화면을 이해하는 Visual Intelligence&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;예를 들어 메시지로 받은 항공편 정보를 읽고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;ldquo;이 일정 캘린더에 추가하고 엄마에게 도착 시간도 보내줘&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;라고 말하면 여러 앱을 넘나들며 작업을 수행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2. Apple Intelligence가 운영체제 전체로 확장되었다&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;작년 WWDC에서 공개된 Apple Intelligence는 다소 제한적인 기능처럼 보였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;하지만 올해는 이야기가 달랐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Apple은 Apple Intelligence를 iOS, iPadOS, macOS, watchOS, visionOS 등 거의 모든 플랫폼에 통합했습니다. &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&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: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Safari AI 탭 정리&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사진 AI 편집&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;자연어 기반 Shortcuts 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;스마트 텍스트 작성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;AI 기반 검색&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;등이 추가되었습니다. &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이제 AI는 특정 앱의 기능이 아니라 운영체제 자체의 기능으로 들어오기 시작했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;3. iOS 27은 AI 중심 업데이트였다&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;예전 WWDC가 UI와 디자인 변화 중심이었다면 이번 iOS 27은 AI가 핵심이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&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: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Liquid Glass 투명도 조절&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;검색 기능 개선&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사진 앱 강화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;성능 향상&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Spotlight 고도화&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;등의 업데이트가 포함되었습니다. &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;다만 솔직히 말하면 이번 iOS 27에서 기억에 남는 것은 새로운 디자인보다 Siri AI였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;4. 모든 플랫폼이 AI 중심으로 재정렬되고 있다&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;iPhone만의 이야기가 아니었습니다.&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: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;macOS Golden Gate&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;iPadOS 27&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;watchOS 27&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;visionOS 27&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모두 Siri AI와 Apple Intelligence를 중심으로 업데이트되었습니다. &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;특히 macOS는 이제 Intel Mac 지원을 완전히 종료하고 Apple Silicon 전용 시대에 들어갔습니다. &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이는 애플이 앞으로 AI 성능 최적화를 Apple Silicon 중심으로 밀어붙이겠다는 선언처럼 느껴졌습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;iOS 개발자로서 가장 인상 깊었던 점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사실 기능 하나하나보다 더 인상 깊었던 것은 애플의 태도 변화였습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;지난 몇 년 동안 애플은 AI 경쟁에 대해 비교적 조심스러운 입장을 유지해 왔습니다. AI 열풍이 업계를 뒤덮는 동안에도 애플은 다른 빅테크 기업들처럼 적극적으로 경쟁에 뛰어드는 모습은 아니었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;하지만 이번 WWDC는 달랐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;ldquo;이제 AI가 플랫폼의 중심이다&amp;rdquo;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;라는 메시지를 던진 것처럼 보였습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그 변화는 Siri부터 운영체제, 개발 도구, Apple Silicon 전략까지 전부 연결되어 있었습니다. 이로인해 iOS 개발자로써의 역할도 달라질것으로 생각합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번 WWDC를 보면서 느낀 점은 이제 AI가 단순히 앱에 추가되는 기능이 아니라 플랫폼 자체의 일부가 되고 있다는 점입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그동안 앱 개발은 사용자의 입력을 받아 정해진 비즈니스 로직을 수행하고 결과를 반환하는 구조가 대부분이었습니다. 개발자의 역할 역시 화면을 설계하고 API를 연결하며 사용자 경험을 만드는 데 집중되어 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;하지만 Apple Intelligence와 새로운 Siri를 보면서 앞으로는 개발자가 고민해야 할 영역이 조금 달라질 것 같다는 생각이 들었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이제 중요한 것은 얼마나 복잡한 로직을 작성하고 구현하느냐 보다, &lt;b&gt;AI가 사용자의 의도를 정확히 이해할 수 있도록 충분한 컨텍스트를 제공하는 것&lt;/b&gt;이 아닐까 싶습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;예를 들어 앞으로는 App Intent, Semantic Search, Apple Intelligence 연동 등을 통해 앱 내부 데이터와 기능을 AI가 이해할 수 있는 형태로 노출해야 할 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사용자가 앱을 직접 실행해서 버튼을 누르는 것이 아니라, &amp;ldquo;지난주 운동 기록을 분석해서 가장 부족했던 부분 알려줘&amp;rdquo; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;라고 말했을 때 AI가 앱의 데이터를 이해하고 적절한 기능을 호출할 수 있어야 할 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;결국 앞으로의 iOS 개발자는 단순히 화면과 API를 연결하는 사람이 아니라, AI가 우리 앱을 이해할 수 있도록 컨텍스트를 설계하는 사람에 가까워질 것 같습니다. 과거에는&amp;nbsp;사용자가&amp;nbsp;앱을&amp;nbsp;이해해야&amp;nbsp;했다면,&amp;nbsp;앞으로는&amp;nbsp;앱이&amp;nbsp;AI를&amp;nbsp;통해&amp;nbsp;사용자를&amp;nbsp;이해하는&amp;nbsp;방향으로&amp;nbsp;변화할지도&amp;nbsp;모르겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;어쩌면 몇 년 뒤에는 &amp;ldquo;프롬프트 엔지니어링&amp;rdquo;이라는 단어보다도 &amp;ldquo;AI를 위한 앱 설계&amp;rdquo;가 더 중요한 역량이 될지도 모르겠습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 글은 여기까지 마치고, 다음 글에서는 WWDC 2026에서 공개된 Xcode AI, Swift 개발 환경 변화, 그리고 실제 개발 생산성 측면에서 어떤 변화가 있었는지 좀 더 자세히 살펴보겠습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;긴 글 읽어주셔서&amp;nbsp;감사합니다.  &amp;zwj;♂️&lt;/span&gt;&lt;/p&gt;</description>
      <category> /WWDC</category>
      <category>2026</category>
      <category>ios</category>
      <category>WWDC</category>
      <category>WWDC 2026</category>
      <category>개발자</category>
      <author>찬히히</author>
      <guid isPermaLink="true">https://chanhhh.tistory.com/363</guid>
      <comments>https://chanhhh.tistory.com/363#entry363comment</comments>
      <pubDate>Thu, 18 Jun 2026 16:44:37 +0900</pubDate>
    </item>
    <item>
      <title>[Swift] Dispatch / Static Dispatch / Dynamic Dispatch</title>
      <link>https://chanhhh.tistory.com/358</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Dispatch ?&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;어떤 메서드를 호출할지 언제 결정하느냐&quot;의 문제&lt;/p&gt;
&lt;pre id=&quot;code_1770780328373&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;player.move()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드에서 실제로 어떤 move가 실행될지&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴파일 타임에 결정되면 -&amp;gt; 정적 디스패치&lt;/li&gt;
&lt;li&gt;런타임에 결정되면 -&amp;gt; 동적 디스패치&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정적 디스패치(Static Dispatch)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;/li&gt;
&lt;li&gt;인라이닝 가능&lt;/li&gt;
&lt;li&gt;오버헤드 거의 없음&lt;/li&gt;
&lt;li&gt;다형성 X&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1770780535182&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 값 타입 (struct / enum)
struct Player {
    func move() {
        print(&quot;move&quot;)
    }
}

// final class 메서드
final class Player {
    func move() {}
}

// private / fileprivate 메서드
class Player {
    private func move() {}
}

// extension 메서드 (class에서 override 안 되는 경우)
class Player {}

extension Player {
    func move() {}
}&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;성능 특성&lt;/li&gt;
&lt;li&gt;직접 함수 주소 호출&lt;/li&gt;
&lt;li&gt;vtable 탐색 없음&lt;/li&gt;
&lt;li&gt;메모리 접근 최소화&lt;/li&gt;
&lt;li&gt;CPU branch prediction 유리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;동적 디스패치 (Dynamic Dispatch)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;/li&gt;
&lt;li&gt;다형성 O&lt;/li&gt;
&lt;li&gt;ovveride 가능&lt;/li&gt;
&lt;li&gt;유연성 높음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1770792283374&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// class + override
// vtable 기반 동적 디스패치
class Animal {
    func speak() {}
}

class Dog: Animal {
    override func speak() {}
}

// protocol (existential 타입)
// witness table 기반 동적 디스패치
protocol Moveable {
    func move()
}

func run(_ object: Moveable) {
    object.move()
}

// @objc / dynamic
// Objective-C runtime 기반 (메시지 디스패치)
// 가장 느림
class Player: NSObject {
    @objc dynamic func move() {}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;내부 동작 차이&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 95px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;방식&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;내부 메커니즘&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;속도&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 25px;&quot;&gt;
&lt;td style=&quot;height: 25px;&quot;&gt;&lt;span&gt;정적&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 25px;&quot;&gt;&lt;span&gt;direct call&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 25px;&quot;&gt;&lt;span&gt;가장 빠름&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;class&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;vtable&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;빠름&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;witness table&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;중간&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;@objc dynamic&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;objc_msgSend&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span&gt;가장 느림&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&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;200&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H11Xo/dJMcacB14iy/8bjOHJBX5XlzutKJ7SKXT0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H11Xo/dJMcacB14iy/8bjOHJBX5XlzutKJ7SKXT0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H11Xo/dJMcacB14iy/8bjOHJBX5XlzutKJ7SKXT0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH11Xo%2FdJMcacB14iy%2F8bjOHJBX5XlzutKJ7SKXT0%2Fimg.webp&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;200&quot; height=&quot;112&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> /Swift</category>
      <category>dispatch</category>
      <category>dynamic</category>
      <category>static</category>
      <author>찬히히</author>
      <guid isPermaLink="true">https://chanhhh.tistory.com/358</guid>
      <comments>https://chanhhh.tistory.com/358#entry358comment</comments>
      <pubDate>Wed, 11 Feb 2026 16:07:53 +0900</pubDate>
    </item>
    <item>
      <title>[SwiftUI] View modifier(onChange, onReceive...</title>
      <link>https://chanhhh.tistory.com/357</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;View&amp;nbsp;modifier&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;계열&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;&lt;span&gt;대표 API&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;트리거 기준&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;값 변화&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;onChange&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;SwiftUI 상태 비교&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;이벤트&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;onReceive&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Publisher emit&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;생명주기&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;onAppear&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;View 등장&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;비동기&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;task(id:)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;id 변경&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;앱 상태&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;scenePhase&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;시스템 상태&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;입력&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;onSubmit&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;유저 입력&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;레이아웃&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Geometry / Preference&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;레이아웃 변화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;제스처&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;onTap / gesture&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;사용자 액션&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뷰 모디파이어는 위와 같은 API들이 있으며, 이번 포스팅에서는 onChange, onReceive에 대해서 알아보려고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1395&quot; data-origin-height=&quot;1956&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o6j0g/dJMcagqP9Gr/otFbOxWcByujCeYDnKYXbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o6j0g/dJMcagqP9Gr/otFbOxWcByujCeYDnKYXbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o6j0g/dJMcagqP9Gr/otFbOxWcByujCeYDnKYXbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo6j0g%2FdJMcagqP9Gr%2FotFbOxWcByujCeYDnKYXbK%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;1395&quot; height=&quot;1956&quot; data-origin-width=&quot;1395&quot; data-origin-height=&quot;1956&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;onChange의 개념 (SwiftUI 값-기반 변화 감지)&lt;/b&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&gt;&lt;b&gt;트리거 기준:&lt;/b&gt;&lt;/span&gt; &amp;ldquo;이 뷰가 업데이트되는 과정에서&amp;rdquo; 관찰 중인 &lt;span&gt;value&lt;/span&gt;를 다시 읽었을 때, &lt;span&gt;&lt;b&gt;직전 값과 &lt;/b&gt;&lt;b&gt;!=&lt;/b&gt;&lt;b&gt;(Equatable 비교)&lt;/b&gt;&lt;/span&gt; 이면 실행.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&amp;ldquo;값(value)의 변화&amp;rdquo;에 반응하는 훅&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;무엇을 감지하나?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;of:&lt;/span&gt;로 넘긴 &lt;span&gt;&lt;b&gt;값 자체&lt;/b&gt;&lt;/span&gt;의 &amp;ldquo;이전 값 vs 현재 값&amp;rdquo;을 비교해서,&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;달라졌을 때만&lt;/b&gt;&lt;/span&gt; action을 실행합니다. (&lt;span&gt;Equatable&lt;/span&gt; 기반)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;언제 실행되나? (핵심)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;값이 바뀌는 &amp;ldquo;순간&amp;rdquo;에 즉시 실행되는 게 아니라,&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SwiftUI가 뷰를 업데이트(=body 재평가)하는 흐름 안에서&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;새 값을 읽고&lt;/li&gt;
&lt;li&gt;이전 값과 비교한 뒤&lt;/li&gt;
&lt;li&gt;다르면 실행합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 더 정확한 개념은:&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;color: #0e0e0e; text-align: start;&quot;&gt;onChange&lt;/span&gt;&lt;span style=&quot;color: #0e0e0e; text-align: start;&quot;&gt;는 &amp;ldquo;값이 바뀌면&amp;rdquo;이 아니라&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0e0e0e; text-align: start;&quot;&gt;&amp;ldquo;값이 바뀐 상태로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;SwiftUI가 그 변화를 관측할 기회가 생겼을 때&lt;/b&gt;&lt;span style=&quot;color: #0e0e0e; text-align: start;&quot;&gt;&amp;rdquo; 실행됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 이렇게 설계됐나?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SwiftUI는 UI를 &amp;ldquo;명령형으로 이벤트 처리&amp;rdquo;하는 방식이 아니라,&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;상태(state)가 바뀌면&lt;/li&gt;
&lt;li&gt;그 결과로 View가 다시 계산되고&lt;/li&gt;
&lt;li&gt;UI가 그려지는 구조입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;onChange&lt;/span&gt;는 이 흐름에 맞춰서 &amp;ldquo;상태 변화 &amp;rarr; 사이드이펙트&amp;rdquo;를 연결하는 도구입니다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;초기 실행은?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;iOS 17+의 &lt;/span&gt;onChange(of:initial:)&lt;span&gt;에서&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;initial: false&lt;/span&gt;(기본) &amp;rarr; 처음 나타날 때는 실행 안 함&lt;/li&gt;
&lt;li&gt;&lt;span&gt;initial: true&lt;/span&gt; &amp;rarr; 처음 나타날 때도 1회 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;같은 값 반복이면 실행 안 함 (중복 억제)&lt;/li&gt;
&lt;li&gt;값 기반이라 의도가 명확함 (&amp;ldquo;이 값이 바뀌면 해야 하는 일&amp;rdquo;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주의점 (개념적으로 꼭 알아야 하는 2가지)&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;이 뷰가 그 값을 &amp;ldquo;관찰하는 구조&amp;rdquo;여야 안정적&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@State&lt;span&gt;, &lt;/span&gt;@Binding&lt;span&gt;, &lt;/span&gt;@ObservedObject/@StateObject&lt;span&gt;, &lt;/span&gt;@Environment&lt;span&gt; 등&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;rarr; 값 변경이 뷰 업데이트로 이어지는 연결고리가 있어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;값이 큰 타입이면 비교 비용이 커질 수 있음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;큰 배열/큰 struct를 그대로 넣으면 &lt;span&gt;==&lt;/span&gt;가 무거워질 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;더 정확한 문장&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span&gt;value&lt;/span&gt; 자체가 바뀌는 순간에 바로 실행되는 게 아니라, &lt;span&gt;&lt;b&gt;그 값이 바뀐 상태로 SwiftUI가 뷰 업데이트를 수행하면서&lt;/b&gt;&lt;/span&gt; 이전 값과 비교해 &amp;ldquo;바뀌었네?&amp;rdquo;가 확인되는 시점에 실행된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉 &lt;/span&gt;&lt;span&gt;onChange&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;b&gt;SwiftUI의 업데이트 사이클에 종속&lt;/b&gt;&lt;span&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&gt;&lt;b&gt;중복 호출:&lt;/b&gt;&lt;/span&gt; 같은 값이면 실행 안 함(Equatable 비교니까).&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;초기 실행:&lt;/b&gt;&lt;/span&gt; 기본은 &lt;span&gt;&lt;b&gt;처음 등장 때는 실행 안 함&lt;/b&gt;&lt;/span&gt;. iOS 17+의 &lt;span&gt;initial: true&lt;/span&gt;를 켜면 1회 실행.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1395&quot; data-origin-height=&quot;1098&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTWTXA/dJMcacBZb44/csjbK7FsibhK4Ije6EUqCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTWTXA/dJMcacBZb44/csjbK7FsibhK4Ije6EUqCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTWTXA/dJMcacBZb44/csjbK7FsibhK4Ije6EUqCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTWTXA%2FdJMcacBZb44%2FcsjbK7FsibhK4Ije6EUqCK%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;1395&quot; height=&quot;1098&quot; data-origin-width=&quot;1395&quot; data-origin-height=&quot;1098&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;onReceive의 개념 (Combine 이벤트-기반 수신)&lt;/b&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&gt;&lt;b&gt;트리거 기준:&lt;/b&gt;&lt;/span&gt; publisher가 &lt;span&gt;&lt;b&gt;emit(방출)&lt;/b&gt;&lt;/span&gt; 할 때마다 실행.&lt;/li&gt;
&lt;li&gt;SwiftUI 업데이트/Equatable 비교 같은 건 상관없고, &lt;span&gt;&lt;b&gt;이벤트가 오면 무조건 실행&lt;/b&gt;&lt;/span&gt;(값이 같아도 실행).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&amp;ldquo;이벤트(event stream)&amp;rdquo;에 반응하는 훅&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;무엇을 감지하나?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Combine &lt;span&gt;Publisher&lt;/span&gt;가 emit하는 &lt;span&gt;&lt;b&gt;이벤트&lt;/b&gt;&lt;/span&gt;를 감지합니다.&lt;/li&gt;
&lt;li&gt;이벤트가 오면 &lt;span&gt;&lt;b&gt;매번&lt;/b&gt;&lt;/span&gt; action 실행 (값이 같아도 실행)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;언제 실행되나?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;뷰가 화면에 존재하면서 publisher를 구독하고 있는 동안&lt;/li&gt;
&lt;li&gt;publisher가 emit하면 실행됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SwiftUI의 body 업데이트와는 독립적&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉:&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span&gt;onReceive&lt;/span&gt;는 &amp;ldquo;뷰 상태 변화&amp;rdquo;가 아니라 &amp;ldquo;외부에서 날아오는 이벤트 스트림&amp;rdquo;을 받아서 처리하는 도구다.&lt;b&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&amp;ldquo;처음 등록될 때 1회는 무조건 실행&amp;rdquo;은 맞나?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;반은 맞고 반은 틀려요.&lt;/b&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&gt;onReceive&lt;/span&gt; 자체가 그런 규칙이 있는 게 아니라,&lt;/li&gt;
&lt;li&gt;&amp;ldquo;publisher 종류&amp;rdquo;에 따라 다릅니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구독하자마자 값 1회 주는 애들&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CurrentValueSubject&lt;/li&gt;
&lt;li&gt;@Published&lt;span&gt;의 publisher (&lt;/span&gt;$value&lt;span&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;rarr; &amp;ldquo;현재 값&amp;rdquo;을 들고 있어서 구독 즉시 한 번 보내는 성향이 흔함&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구독해도 아무것도 안 주는 애들&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PassthroughSubject&lt;/li&gt;
&lt;li&gt;&amp;rarr; &lt;span&gt;send()&lt;/span&gt;가 오기 전까지는 아무 이벤트도 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;타이머&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Timer.publish(...).autoconnect()&lt;/li&gt;
&lt;li&gt;&amp;rarr; 즉시 1회가 아니라 &amp;ldquo;틱 주기&amp;rdquo;에 따라 들어옴&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부 이벤트를 UI에 연결하기 좋음&lt;/li&gt;
&lt;li&gt;뷰 업데이트에 의존하지 않음 (스트림이면 스트림대로 받음)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주의점 (여기가 퍼포먼스/버그의 핵심)&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;이벤트 빈도 = 호출 빈도&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고빈도 스트림이면 action이 폭주할 수 있음&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&amp;rarr; &lt;/span&gt;removeDuplicates&lt;span&gt;, &lt;/span&gt;throttle&lt;span&gt;, &lt;/span&gt;debounce&lt;span&gt; 같은 제어가 필요할 때가 많음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스레드/액터 컨텍스트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;publisher가 백그라운드에서 emit하면 action도 그쪽에서 불릴 수 있음&lt;/li&gt;
&lt;li&gt;UI 상태 변경은 main에서 해야 안전&lt;/li&gt;
&lt;li&gt;&amp;rarr; 필요하면 &lt;span&gt;receive(on:)&lt;/span&gt;로 메인에 올림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;선택 기준을 한 줄로 정리하면&lt;/b&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;b&gt;내가 감지하려는 게 &amp;ldquo;값의 변화&amp;rdquo;면&lt;/b&gt;&lt;span&gt; &amp;rarr; onChange = &amp;ldquo;렌더링 중 값이 바뀐 걸 발견하면 반응&amp;rdquo;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내가 감지하려는 게 &amp;ldquo;이벤트 스트림&amp;rdquo;이면&lt;/b&gt;&lt;span&gt; &amp;rarr; onReceive&amp;nbsp;=&amp;nbsp;&amp;ldquo;이벤트&amp;nbsp;스트림이&amp;nbsp;오면&amp;nbsp;즉시&amp;nbsp;반응&amp;rdquo;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&amp;ldquo;원천이 Combine Publisher라면 onReceive가 자연스럽고, SwiftUI 상태/바인딩/환경값이라면 onChange가 자연스럽다.&amp;rdquo;&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;짧은 예시&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ onChange가 딱 맞는 예&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1770196451375&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@State var isOn: Bool

Toggle(&quot;Auto Upload&quot;, isOn: $isOn)
  .onChange(of: isOn) {
     // 토글이 바뀌면 설정 저장
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ onReceive가 딱 맞는 예&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1770196464756&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
    // 앱이 active 될 때마다 새로고침
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> /Swift</category>
      <category>onChange</category>
      <category>OnReceive</category>
      <category>swiftUI</category>
      <category>View modifier</category>
      <author>찬히히</author>
      <guid isPermaLink="true">https://chanhhh.tistory.com/357</guid>
      <comments>https://chanhhh.tistory.com/357#entry357comment</comments>
      <pubDate>Wed, 4 Feb 2026 18:15:28 +0900</pubDate>
    </item>
    <item>
      <title>행렬 회전</title>
      <link>https://chanhhh.tistory.com/356</link>
      <description>&lt;pre id=&quot;code_1758530886337&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;vector&amp;gt;
using namespace std;

// 시계방향 90도 회전
vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; rotate_array_90(const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; array) {
    int n = array.size();
    int m = array[0].size();
    vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; rotated(m, vector&amp;lt;int&amp;gt;(n));
    
    for (int i = 0; i &amp;lt; n; i++) {
        for (int j = 0; j &amp;lt; m; j++) {
            rotated[j][n - 1 - i] = array[i][j];
        }
    }
    return rotated;
}

// 시계방향 180도 회전
vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; rotate_array_180(const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; array) {
    int n = array.size();
    int m = array[0].size();
    vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; rotated(n, vector&amp;lt;int&amp;gt;(m));
    
    for (int i = 0; i &amp;lt; n; i++) {
        for (int j = 0; j &amp;lt; m; j++) {
            rotated[n - 1 - i][m - 1 - j] = array[i][j];
        }
    }
    return rotated;
}

// 시계방향 270도 회전 ( == 반시계방향 90도 )
vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; rotate_array_270(const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; array) {
    int n = array.size();
    int m = array[0].size();
    vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; rotated(m, vector&amp;lt;int&amp;gt;(n));
    
    for (int i = 0; i &amp;lt; n; i++) {
        for (int j = 0; j &amp;lt; m; j++) {
            rotated[m - 1 - j][i] = array[i][j];
        }
    }
    return rotated;
}

// 전치 행렬 (transpose)
vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; transpose_array(const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; array) {
    int n = array.size();
    int m = array[0].size();
    vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; transposed(m, vector&amp;lt;int&amp;gt;(n));
    
    for (int i = 0; i &amp;lt; n; i++) {
        for (int j = 0; j &amp;lt; m; j++) {
            transposed[j][i] = array[i][j];
        }
    }
    return transposed;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category> &amp;zwj; /C &amp;amp; C++</category>
      <author>찬히히</author>
      <guid isPermaLink="true">https://chanhhh.tistory.com/356</guid>
      <comments>https://chanhhh.tistory.com/356#entry356comment</comments>
      <pubDate>Mon, 22 Sep 2025 17:49:44 +0900</pubDate>
    </item>
    <item>
      <title>[삼체] 2부: 암흑의 숲 독후감</title>
      <link>https://chanhhh.tistory.com/352</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MnIcu/btsMOXook76/jGzOdxXRnV6KI7KcWckdP1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MnIcu/btsMOXook76/jGzOdxXRnV6KI7KcWckdP1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MnIcu/btsMOXook76/jGzOdxXRnV6KI7KcWckdP1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMnIcu%2FbtsMOXook76%2FjGzOdxXRnV6KI7KcWckdP1%2Fimg.webp&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;375&quot; height=&quot;524&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 글은 스포일러가 &lt;b&gt;약간 포함&lt;/b&gt;되어 있습니다.&lt;br /&gt;&lt;br /&gt;지난번 삼체 1부: 삼체문제를 읽고 난 후, 머릿속을 떠나지 않는 궁금증 때문에 바로 삼체 2부: 암흑의 숲을 펼쳤습니다. (이하 암흑의 숲)&lt;br /&gt;1부가 과학과 철학이 절묘하게 결합된 문제 제기에 집중했다면, 2부는 훨씬 더 거대한 스케일로 확장되며 &amp;lsquo;문제 해결&amp;rsquo;과 &amp;lsquo;생존&amp;rsquo;이라는 현실적인 주제를 정면으로 다룹니다.&lt;br /&gt;&lt;br /&gt;암흑의 숲을 읽는 대부분의 시간은 출퇴근 길이었는데, 책을 한번 펼쳐 몇 페이지 읽다 보면 어느새 회사 앞에 도착해 있는, 마치  SF 같은 일들이 저에게도 일어나곤 했습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;책의 주요 전개는 인류와 외계 문명의 충돌을 둘러싼 '면벽자' vs '파벽자' 구조로 진행됩니다. 면벽자 만이 가질 수 있는 인류의 대표의 고뇌와 그 고뇌를 타파하여 무력화시키려는 파벽자의 전개로 흘러갑니다. 이 두 구조의 움직임이 교차하면서, 인류가 처한 절망적인 상황이 더욱 선명하게 부각됩니다.&amp;nbsp; 후반부에는 단순히 인류 내부의 갈등을 다루는 데 그치지 않고, '우주 사회학'이라는 개념을 중심으로 전개됩니다. 이 과정에서 암흑의 숲 이론이라는 충격적인 가설이 등장하는데, 이를 처음 접했을 때는 마치 새로운 차원의 사고를 여는 듯한 경험이었습니다. 인류가 처한 절망적인 상황과, 그에 대한 해결책을 찾는 과정이 너무도 논리적으로 전개되었기에 SF를 읽으면서도 철학 서적을 탐독하는 듯한 기분이 들었습니다.&lt;br /&gt;&lt;br /&gt;류츠신의 필력은 2부에서도 여전히 빛을 발합니다. 특히, 거대한 시간의 흐름 속에서 펼쳐지는 장대한 이야기와, 그 안에서 인간 개개인이 겪는 감정의 변화가 섬세하게 묘사됩니다. 1부에서는 과학적 설정과 미스터리한 분위기가 중심이었다면, 2부에서는 캐릭터 개개인의 감정선과 선택이 더욱 중요한 요소로 작용하는데, 이 때문에 출퇴근 시간이 기다려질 정도였습니다. 심지어는 더 긴 시간을 책과 함께하고 싶어서 일부러 조금 돌아가는 버스를 타기도 했습니다.&lt;br /&gt;&lt;br /&gt;또한, 삼체문제를 읽을 때도 과학적 요소들이 자연스럽게 스토리에 녹아들어 감탄했었는데, 암흑의 숲에서는 우주적 사고방식과 전략적 사고가 조화롭게 어우러지며, SF적 상상력의 끝을 보여줍니다. 책을 읽는 내내 &amp;lsquo;이런 관점으로 우주를 바라볼 수도 있구나&amp;rsquo;라는 놀라움을 연이어 경험했습니다.&lt;br /&gt;&lt;br /&gt;책을 덮고 난 후, 암흑의 숲 이론이 단순한 소설 속 설정이 아니라 현실에서도 적용될 수 있는 이론처럼 느껴져 머릿속에서 계속 맴돌았습니다. &amp;lsquo;과연 우리가 우주에서 지적 생명체를 찾는 것이 옳은 일일까?&amp;rsquo;라는 질문이 문득 떠오르게 되었습니다. 우주를 생각하는 일이 이전보다 훨씬 더 무겁게 느껴지고 더 흥미로운 호기심으로 채워지게 되었습니다. 이 책을 통해 SF 장르가 단순한 오락이 아니라 사유의 도구가 될 수 있음을 다시금 깨닫게 되었습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사실 이 글을 쓰는 시점에서 저는 이미 삼체 3부: 사신의 영생을 거의 다 읽어가고 있습니다. 그리고 한 가지 확신할 수 있는 것은, 3부는 정말 더더더 재밌습니다. 1부가 호기심을 자극하고, 2부가 충격과 사고의 확장을 선사했다면, 3부는 그 모든 것을 뛰어넘어 전혀 예상치 못한 방향으로 이야기를 끌고 갑니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 거대한 이야기가 어디로 향할지, 류츠신이 펼쳐놓은 우주의 끝은 과연 무엇을 보여줄지, 마지막까지 차분히 따라가 보려고 합니다. 여러분도 함께 같이 가시죠.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;'암흑의 숲'의 독후감을 이만 마칩니다. 읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>KIM CHAN HEE/ </category>
      <category>2부</category>
      <category>삼체</category>
      <category>암흑의숲</category>
      <author>찬히히</author>
      <guid isPermaLink="true">https://chanhhh.tistory.com/352</guid>
      <comments>https://chanhhh.tistory.com/352#entry352comment</comments>
      <pubDate>Tue, 18 Mar 2025 23:07:41 +0900</pubDate>
    </item>
  </channel>
</rss>