<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>eung7.archive</title>
    <link>https://eung7.tistory.com/</link>
    <description>App Developer</description>
    <language>ko</language>
    <pubDate>Wed, 19 Aug 2026 22:21:42 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Eung7</managingEditor>
    <image>
      <title>eung7.archive</title>
      <url>https://tistory1.daumcdn.net/tistory/5370865/attach/5efc01cc83754795ae8670a38689e1f4</url>
      <link>https://eung7.tistory.com</link>
    </image>
    <item>
      <title>Agile(에자일)과 Scrum(스크럼), 소프트웨어 개발 방법론에 대해서</title>
      <link>https://eung7.tistory.com/38</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;소프트웨어 개발 방법론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어 개발 방법론은 앱을 제작함에 있어서 필요한 개발 과정들을 정리하고 표준화하는 것을 의미합니다. 각 개발자들이 개발과정에서의 일관성을 유지하고 효과적인 협업이 이루어질 수 있도록 돕는 방법론입니다. 이번 글에서는 Agile과 Scrum 방법론에 대해 언급할 예정입니다.&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;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dTpJ4d/btsGYZUgJZV/77JIOR9iQKFE9gCOx6hDSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dTpJ4d/btsGYZUgJZV/77JIOR9iQKFE9gCOx6hDSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dTpJ4d/btsGYZUgJZV/77JIOR9iQKFE9gCOx6hDSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdTpJ4d%2FbtsGYZUgJZV%2F77JIOR9iQKFE9gCOx6hDSk%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;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Agile(에자일)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agile은&lt;b&gt; 날렵한&lt;/b&gt;, &lt;b&gt;재빠른&lt;/b&gt; 이라는 뜻을 가지고 있습니다. 이 방법론은 빠르게 변화하고 있는 시장의 요구사항에 기민하게 대처하기 위한 방법론입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;Scrum(스크럼)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agile 방법론을 구체화한 여러 프로세스 중 한 가지입니다. 스프린트라고 불리는 1-4주의 짧은 개발 주기로 나누고 각 주기마다 개발, 리뷰, 회고 등에 과정을 거치는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&lt;/b&gt; 프로덕트 오너가 제품의 요구 사항을 백로그에 작성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.&lt;/b&gt; 스프린트에 대한 계획을 구체적으로 설계합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3.&lt;/b&gt; 1-4주의 스프린트 동안 기능을 개발합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4.&lt;/b&gt; 데일리 스크럼 미팅을 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5.&lt;/b&gt; 산출물에 대한 리뷰와 피드백 과정을 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6.&lt;/b&gt; 스프린트를 회고합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 시장에 발빠른 대응을 위해서 많은 기업들이나 스타트업에서도 해당 소프트웨어 개발 방법론을 채택하고 있습니다. 가장 많이 사용하는 툴은 JIRA가 될 수 있겠는데요. 하지만 이제 Notion 및 GitHub Project를 통해서 운용되고 있는 곳들도 생겨나고 있습니다.&lt;/p&gt;</description>
      <category>소프트웨어 공학</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/38</guid>
      <comments>https://eung7.tistory.com/38#entry38comment</comments>
      <pubDate>Mon, 29 Apr 2024 09:58:21 +0900</pubDate>
    </item>
    <item>
      <title>Dart에서 final과 const의 차이와 사용법</title>
      <link>https://eung7.tistory.com/35</link>
      <description>&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;/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;Dart를 사용할 때, 변수를 선언할 때 final과 const는 자주 사용되는 것을 볼 수 있습니다. 이번 글에서는 두 개의 차이점과 목적을 제대로 바로잡고, Flutter 앱을 효율적으로 제작할 수 있는 사용법에 대해서 알아보겠습니다.&lt;/span&gt;&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;fianl 이해하기&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;code&gt;final&lt;/code&gt;은 한 번 값이 주입된 변수에 다시 변경될 수 없습니다. 만약 final로 변수가 선언되면, 변수의 선언부나 클래스의 생성자로 부터 한 번만 값이 주입될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;class Circle {
 final double radius;

 Circle(this.radius);

 double calculateArea() {
 return 3.14 * radius * radius;
 }
}
void main() {
 final Circle circle = Circle(5.0);
 print(circle.calculateArea()); // Output: 78.5

 // Attempting to reassign a final variable throws a compile-time error
 circle = Circle(10.0); // Error: The final variable 'circle' can't be assigned a value.
}&lt;/code&gt;&lt;/pre&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;final의 장점&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; color: #333333; text-align: start;&quot;&gt;final을 사용하면 다음과 같은 장점을 얻을 수 있습니다.&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;&lt;b&gt;값이 변경되는 것이 보장&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;만약 앱이 실행되고 일정한 값을 유지할 경우에는 final변수가 유용할 수 있습니다. 개발자에게 데이터의 무결성을 보장하고 의도하지 않은 수정을 방지할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;성능 최적화&lt;br /&gt;&lt;/b&gt;일반적으로 final변수는 Dart 컴파일러에 의해 최적화되어 일반 변수보다 성능이 향상될 수 있습니다. 한 번 할당하면 런타임 검사 없이 바로 메모리에 저장됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스레드 안정성&lt;br /&gt;&lt;/b&gt;본질적으로 값이 변경될 수 없는 final변수는 스레드 안정성이 있고, 동시성 프로그래밍에 적합합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;final의 효율적인 사용법&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;변수를 선언하거나 클래스 생성자 내에서 final변수를 초기화합니다.&lt;/li&gt;
&lt;li&gt;final변수에 값을 재할당을 하는 것은 하지말아야합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;const 이해하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const 키워드는 컴파일 타임에 선언되는 변수입니다. final과 달리, const 변수는 변수 선언과 함께 값이 할당되어야합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714304148741&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main() {
 const double pi = 3.14;
 const int daysInWeek = 7;
 
 print(pi); // Output: 3.14
 print(daysInWeek); // Output: 7
 
 // Attempting to reassign a const variable throws a compile-time error
 pi = 3.14159; // Error: Setter not found: 'pi'.
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;const의 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;성능 최적화&lt;/b&gt;&lt;br /&gt;컴파일 타임에 변수가 정해지므로 런타임에서 성능이 향상될 수 밖에 없습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메모리 효율성&lt;/b&gt;&lt;br /&gt;컴파일 타임에 변수가 정해지고, 단일 메모리 공간에 저장이 되기 떄문에 메모리 사용량을 줄일 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;코드 최적화&lt;/b&gt;&lt;br /&gt;const를 사용하는 것은 중복된 계산을 줄여줄 수 있어서 코드 효율성을 향상 시킬 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;const의 효율적인 사용법&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;복잡한 객체나 상수가 아닌 값과 관련된 표현식과 함께 사용할 때는 주의해야합니다. 이는 예상치 못한 동작을 일으킬 수 있습니다.&lt;/li&gt;
&lt;li&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;final과 const는 Flutter와 Dart에서 변수 선언에서 불변성과 최적화를 가능하게 하는 강력한 키워드입니다. 이들의 차이점과 최상의 실천 방법을 이해하는 것은 효율적이고 유지보수 가능한 코드를 작성하는 데 중요합니다. &quot;final&quot;과 &quot;const&quot;를 효과적으로 활용함으로써 개발자는 성능, 메모리 사용량, 코드 가독성을 향상시키고 의도하지 않은 변수 수정과 관련된 버그를 방지할 수 있습니다. 최상의 실천 방법을 준수함으로써 Flutter와 Dart 프로젝트에서 &quot;final&quot;과 &quot;const&quot;의 적절한 사용을 보장하여 더 견고하고 신뢰할 수 있는 응용 프로그램을 만들 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Reference&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/@yetesfadev/demystifying-final-and-const-in-flutter-and-dart-4d6dbc4cbbb8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://medium.com/@yetesfadev/demystifying-final-and-const-in-flutter-and-dart-4d6dbc4cbbb8&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1714304737217&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Demystifying &amp;ldquo;final&amp;rdquo; and &amp;ldquo;const&amp;rdquo; in Flutter and Dart:&quot; data-og-description=&quot;In Flutter and Dart programming, the keywords &amp;ldquo;final&amp;rdquo; and &amp;ldquo;const&amp;rdquo; play a crucial role in defining variables and constants. Understanding&amp;hellip;&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/@yetesfadev/demystifying-final-and-const-in-flutter-and-dart-4d6dbc4cbbb8&quot; data-og-url=&quot;https://medium.com/@yetesfadev/demystifying-final-and-const-in-flutter-and-dart-4d6dbc4cbbb8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eyYrQ/hyVVBb7924/uYHwH869n3rLwcWSKCEsJk/img.jpg?width=1200&amp;amp;height=1800&amp;amp;face=0_0_1200_1800,https://scrap.kakaocdn.net/dn/cQkrXq/hyVVG5AFJw/oG7LOI0x5NbPOxNqUWCEok/img.jpg?width=1358&amp;amp;height=905&amp;amp;face=0_0_1358_905,https://scrap.kakaocdn.net/dn/cii0xL/hyVVGLgZsD/sNSCSxETrXiRdxSjgJpTx0/img.jpg?width=1358&amp;amp;height=905&amp;amp;face=0_0_1358_905&quot;&gt;&lt;a href=&quot;https://medium.com/@yetesfadev/demystifying-final-and-const-in-flutter-and-dart-4d6dbc4cbbb8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/@yetesfadev/demystifying-final-and-const-in-flutter-and-dart-4d6dbc4cbbb8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eyYrQ/hyVVBb7924/uYHwH869n3rLwcWSKCEsJk/img.jpg?width=1200&amp;amp;height=1800&amp;amp;face=0_0_1200_1800,https://scrap.kakaocdn.net/dn/cQkrXq/hyVVG5AFJw/oG7LOI0x5NbPOxNqUWCEok/img.jpg?width=1358&amp;amp;height=905&amp;amp;face=0_0_1358_905,https://scrap.kakaocdn.net/dn/cii0xL/hyVVGLgZsD/sNSCSxETrXiRdxSjgJpTx0/img.jpg?width=1358&amp;amp;height=905&amp;amp;face=0_0_1358_905');&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;Demystifying &amp;ldquo;final&amp;rdquo; and &amp;ldquo;const&amp;rdquo; in Flutter and Dart:&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In Flutter and Dart programming, the keywords &amp;ldquo;final&amp;rdquo; and &amp;ldquo;const&amp;rdquo; play a crucial role in defining variables and constants. Understanding&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.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>Flutter/Dart</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/35</guid>
      <comments>https://eung7.tistory.com/35#entry35comment</comments>
      <pubDate>Sun, 28 Apr 2024 20:45:44 +0900</pubDate>
    </item>
    <item>
      <title>이미지 메모리를 효율적으로 관리하는 다운 샘플링</title>
      <link>https://eung7.tistory.com/34</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS를 개발할 때, 이미지를 관리하는 것은 사용자 경험에 있어서 중요한 부분입니다. 높은 해상도를 가지고 있는 이미지들은 메모리 사용량에 큰 영향을 줄 수 있죠. 이번 시간에는 어떻게 효율적으로 이미지 메모리를 줄일 수 있는 방법을 알아보겠습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;다운 샘플링이 필요한 상황들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운 샘플링은 이미지의 퀄리티는 유지하면서 이미지의 사이즈를 줄이고 메모리 사용량을 줄이는 과정입니다. 특히 용량이 큰 이미지들을 작업할 떄 성능의 문제가 생기지 않게 하려면 더욱 필요합니다. 다운 샘플링이 필요한 순간은 다음과 같을 수도 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;갤러리 사진들&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 사용자가 해상도가 높은 사진을 갤러리에서 인터렉션 한다면 어떨까요? 이미지를 로딩 하는 것만으로도 메모리 사용량은 큰 부담을 느낄 것입니다. 특히 오래된 기기들이라면 더 심하죠. 다운 샘플링은 이미지 퀄리티를 유지하면서 사용자 경험을 해치지 않고 갤러리에 많은 이미지를 보여줄 수 있게 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SNS 피드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SNS앱에서는 유저들이 공유하는 이미지들을 보여줘야합니다. 다운 샘플링은 이런 이미지들의 오버헤드를 발생시키지 않게 하고, 사용자로 하여금 스크롤을 더 부드럽게 할 수 있게합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이미지 업로드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저가 이미지를 업로드할 때, 다운 샘플링은 이미지 사이즈를 줄일 수 있습니다. 그렇게 되면 이미지 업로드 속도가 빨라지고 결과적으로 유저 만족도가 올라가게 됩니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;만약 다운 샘플링을 사용하지 않는다면..&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 사이즈가 작은 Image Container에 해상도가 큰 이미지를 보여준다고 생각해봅시다. 예를 들어서 1000x1000 픽셀의 해상도를 가진 이미지가 있지만, 100x100 픽셀을 가지는 Container에 이미지를 넣고 싶은 것 처럼요. 썸네일 이미지나 프로필 이미지가 될 수 있겠네요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운 샘플링을 사용하지 않는다면, 2가지 문제를 직면하게 될 수도 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메모리 오버헤드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1000x1000 픽셀의 이미지를 로드하는 것은 메모리에게 상당한 부담이 됩니다. 이런 메모리 할당이 계속 된다면, 메모리 경고나 심하면 앱의 크래시까지 발생할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;성능에 미치는 영향&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해상도가 큰 이미지를 작은 콘테이너에 보여주는 것은 성능면에서도 영향을 끼칩니다. 일단 작은 이미지로 리스케일 하는 과정에서 렌더링 시간이 집중되어 앱의 부드러움에 영향을 미칠 수 있습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;다운 샘플링&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bInZwf/btsGZyBiOfh/wKMUrSKkKpX8lXZJPK4FLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bInZwf/btsGZyBiOfh/wKMUrSKkKpX8lXZJPK4FLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bInZwf/btsGZyBiOfh/wKMUrSKkKpX8lXZJPK4FLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbInZwf%2FbtsGZyBiOfh%2FwKMUrSKkKpX8lXZJPK4FLk%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;1362&quot; height=&quot;388&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iOS에서 다운 샘플링을 위한 메서드는 다양하게 제공되지만, 가장 현대적이고 효율적인 접근 법은 바로 iOS10에서 소개된 &lt;b&gt;UIGraphicsImageRenderer&lt;/b&gt;을 사용하는 것입니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;import UIKit

func downsampleImage(at url: URL, to targetSize: CGSize) -&amp;gt; UIImage? {
    let renderer = UIGraphicsImageRenderer(size: targetSize)

    return renderer.image { (context) in
        let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
        if let imageSource = CGImageSourceCreateWithURL(url as CFURL, imageSourceOptions),
           let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) {

            let scaleFactor = max(image.width / targetSize.width, image.height / targetSize.height)
            let scaledSize = CGSize(width: image.width / scaleFactor, height: image.height / scaleFactor)

            image.draw(in: CGRect(origin: .zero, size: scaledSize))
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 &lt;code&gt;downsampleImage&lt;/code&gt;라는 이미지 URL과 사이즈에 대한 인자를 받는 메서드를 정의했습니다. 먼저 이미지를 &lt;code&gt;UIImage&lt;/code&gt;가 아닌 &lt;code&gt;CGImage&lt;/code&gt;로 불러옵니다. 그리고 &lt;code&gt;UIGraphicsImageRenderer&lt;/code&gt;의 클로저를 통해 파라미터로 들어온 사이즈를 통해 새로운 이미지로 반환됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;UIGraphicsImageRenderer&lt;/code&gt;를 이용한 장점은 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 간단함&lt;/b&gt;&lt;br /&gt;&lt;code&gt;UIGraphicsImageRenderer&lt;/code&gt;는 클로저의 Context를 통해 이미지 프로세싱을 간단하게 조작할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 메모리 효율성&lt;/b&gt;&lt;br /&gt;개발자가 직접 메모리를 관리하는 대신, 이 객체는 iOS 메모리 관리 시스템에 있어서 최적화를 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 사이즈와 방향 조절&lt;/b&gt;&lt;br /&gt;&lt;code&gt;UIGraphicsImageRenderer&lt;/code&gt;는 자동적으로 사이즈와 방향을 조절해줍니다. 따라서 시스템 내에서 작아진 이미지를 반환하는 것을 보장할 수 있습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;효율적으로 이미지를 관리하는 것은 사용자 경험에 있어서 중요한 역할을 합니다. &lt;code&gt;UIGraphicsImageRenderer&lt;/code&gt;를 이용한 다운 샘플링은 메모리 사용량을 줄이고 성능을 증가할 수 있는 좋은 툴입니다. 다운 샘플링을 구현한다는 것은 앱의 이미지들을 훼손시키지 않고 동시에 성능을 유지할 수 있습니다. 오래된 기기라도요. :)&lt;/p&gt;</description>
      <category>iOS/iOS 응용</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/34</guid>
      <comments>https://eung7.tistory.com/34#entry34comment</comments>
      <pubDate>Sun, 28 Apr 2024 01:07:00 +0900</pubDate>
    </item>
    <item>
      <title>인터럽트와 시스템 콜의 개념과 동작원리</title>
      <link>https://eung7.tistory.com/33</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;유저 모드(User mode)&lt;/h2&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;b&gt;인터럽트(Interrupt)&lt;/b&gt;가 발생하거나 &lt;b&gt;시스템 콜(System call)&lt;/b&gt;을 호출시에는 커널모드로 전환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;커널 모드(Kernel mode)&lt;/h2&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;프로그램의 현재 CPU 상태를 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터럽트나 시스템 콜을 커널 모드에서 직접 처리&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;만약 처리가 완료되면, 중단됐던 프로그램의 CPU 상태를 복원함&lt;/li&gt;
&lt;li&gt;CPU 상태를 복원함과 동시에&lt;b&gt; 통제권을 유저 모드로 반환하여 통제권을 프로그램에게 반환함&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;다시 유저 모드에서는 프로그램이 중단되었던 부분부터 이어서 실행&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;그렇기 때문에 시스템 전반적인 부분이나 하드웨어 같은 부분은 커널 모드에서 관리&lt;/li&gt;
&lt;li&gt;결국 전체 시스템을 보호하기 위해 고안된 모드&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;인터럽트(Interrupt)&lt;/h2&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;b&gt;만약 인터럽트가 발생하면, CPU에서 커널 모드에서 해당 커널 코드를 실행&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;Power에 문제가 발생 시&lt;/li&gt;
&lt;li&gt;I/O 작업 완료 시&lt;/li&gt;
&lt;li&gt;Timer가 다 됐을 시&lt;/li&gt;
&lt;li&gt;0으로 나눴을 시&lt;/li&gt;
&lt;li&gt;유효하지 않은 메모리 공간에 진입했을 시&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시스템 콜(System call)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램이 OS 커널이 제공하는 서비스를 이용하고 싶을 시, 시스템 콜을 실행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;만약 시스템 콜이 발생하면, 해당 커널 코드가 커널 모드에서 실행됨&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;파일 I/O 관련 명령어&lt;/li&gt;
&lt;li&gt;소켓 관련 명령어&lt;/li&gt;
&lt;li&gt;장치(Device) 관련 명령어&lt;/li&gt;
&lt;li&gt;프로세스끼리의 통신 관련 명령어&lt;/li&gt;
&lt;/ul&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;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;싱글 코어 CPU에 프로세스에 2개의 스레드가 있다고 가정&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eung7.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;운영체제의 프로세스 상태에 관한 내용&lt;/a&gt; 참조&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rrUmo/btsGTaAgRYK/3JecRTaOqTEVGsgs2J46o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rrUmo/btsGTaAgRYK/3JecRTaOqTEVGsgs2J46o1/img.png&quot; data-alt=&quot;프로세스의 상태 다이어그램&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rrUmo/btsGTaAgRYK/3JecRTaOqTEVGsgs2J46o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrrUmo%2FbtsGTaAgRYK%2F3JecRTaOqTEVGsgs2J46o1%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;720&quot; height=&quot;220&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로세스의 상태 다이어그램&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;먼저 T1이라는 스레드가 유저 모드에서 실행되고 있다고 가정 (T1: Running 상태, T2: Ready 상태)&lt;/li&gt;
&lt;li&gt;이후 T1 스레드에서 파일을 읽는 READ라는 &lt;b&gt;시스템 콜&lt;/b&gt;을 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1665&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oh5rV/btsGRIR8gPs/bpcc3TlrvE9z50rUkk3ljK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oh5rV/btsGRIR8gPs/bpcc3TlrvE9z50rUkk3ljK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oh5rV/btsGRIR8gPs/bpcc3TlrvE9z50rUkk3ljK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foh5rV%2FbtsGRIR8gPs%2Fbpcc3TlrvE9z50rUkk3ljK%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;1665&quot; height=&quot;235&quot; data-origin-width=&quot;1665&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&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;b&gt;시스템 콜을 실행&lt;/b&gt;하면 유저 모드에서 커널 모드로 컨트롤이 넘어감&lt;/li&gt;
&lt;li&gt;T1의 CPU 상태를 저장&lt;/li&gt;
&lt;li&gt;파일을 READ할 준비&lt;/li&gt;
&lt;li&gt;T1의 Waiting 상태가 되고, Ready 상태에 있는 T2가 스케줄러에 의해 Running 상태가 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1669&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJDlyh/btsGSPiVUP0/TJYpTdKKnDTjk3xK0CCXj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJDlyh/btsGSPiVUP0/TJYpTdKKnDTjk3xK0CCXj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJDlyh/btsGSPiVUP0/TJYpTdKKnDTjk3xK0CCXj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJDlyh%2FbtsGSPiVUP0%2FTJYpTdKKnDTjk3xK0CCXj0%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;1669&quot; height=&quot;288&quot; data-origin-width=&quot;1669&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이후 파일을 READ 완료했다는 &lt;b&gt;인터럽트가 발생&lt;/b&gt;, 유저 모드에서 커널 모드로 컨트롤이 넘어감&lt;/li&gt;
&lt;li&gt;T2의 CPU 상태를 저장&lt;/li&gt;
&lt;li&gt;파일 READ를 완료했으니 T1이 Waiting 상태에서 Ready 상태로 변경&lt;/li&gt;
&lt;li&gt;T2의 CPU 상태를 복원하고 다시 T2를 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1669&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1LwB2/btsGQ3P1oPH/DdA4hNaAQ9SN3D4sfit9g1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1LwB2/btsGQ3P1oPH/DdA4hNaAQ9SN3D4sfit9g1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1LwB2/btsGQ3P1oPH/DdA4hNaAQ9SN3D4sfit9g1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1LwB2%2FbtsGQ3P1oPH%2FDdA4hNaAQ9SN3D4sfit9g1%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;1669&quot; height=&quot;288&quot; data-origin-width=&quot;1669&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;T2가 진행되고 CPU의 Time-Slice 시간이 다 되면, 하드웨어의 &lt;b&gt;Timer 인터럽트가 발생&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;T2의 CPU 상태를 저장&lt;/li&gt;
&lt;li&gt;T2는 주어진 Time-Slice를 다 사용했으니, Ready 상태가 되고, T1은 Running 상태로 전환&lt;/li&gt;
&lt;li&gt;T1의 CPU 상태를 복원하고, 파일을 불러온 지점부터 다시 T1을 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1855&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4JNzM/btsGS9VIHw3/B2w0zjwRVu3Hc64zDJd1tK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4JNzM/btsGS9VIHw3/B2w0zjwRVu3Hc64zDJd1tK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4JNzM/btsGS9VIHw3/B2w0zjwRVu3Hc64zDJd1tK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4JNzM%2FbtsGS9VIHw3%2FB2w0zjwRVu3Hc64zDJd1tK%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;1855&quot; height=&quot;288&quot; data-origin-width=&quot;1855&quot; data-origin-height=&quot;288&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>CS/운영체제</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/33</guid>
      <comments>https://eung7.tistory.com/33#entry33comment</comments>
      <pubDate>Wed, 24 Apr 2024 11:56:34 +0900</pubDate>
    </item>
    <item>
      <title>CPU 스케줄러, 디스패처의 개념과 동작원리</title>
      <link>https://eung7.tistory.com/32</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;운영체제의 프로세스의 상태&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btDGQG/btsGQ4ASYro/sokuCjIESjTGGXFsxIzJ70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btDGQG/btsGQ4ASYro/sokuCjIESjTGGXFsxIzJ70/img.png&quot; data-alt=&quot;OS의 프로세스 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btDGQG/btsGQ4ASYro/sokuCjIESjTGGXFsxIzJ70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtDGQG%2FbtsGQ4ASYro%2FsokuCjIESjTGGXFsxIzJ70%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;720&quot; height=&quot;220&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OS의 프로세스 상태&lt;/figcaption&gt;
&lt;/figure&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;b&gt;New&lt;/b&gt;: 프로세스가 생성된 상태 &amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ready&lt;/b&gt;: CPU에 실행되기 위해 기다리는 상태&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Running&lt;/b&gt;: CPU 스케줄러에 의해 실행되고 있는 상태
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Running 상태에 있는 프로세스는 주어진 Time-Slice시간을 사용하면 다시 Ready상태로 되돌아감&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Waiting&lt;/b&gt;: I/O 작업이나 이벤트를 기다릴 때 동안의 상태, 작업이 완료되면 다시 Ready상태로 되돌아감&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Terminated&lt;/b&gt;: 프로세스가 더 이상 사용되지 않을 때의 상태&lt;/li&gt;
&lt;/ul&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;CPU 스케줄러(Scheduler)&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;Running 상태가 끝나고 다른 프로세스를 선택하는 역할&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Ready Queue에서 다음에 실행될 프로세스를 선택&lt;br /&gt;&lt;b&gt;*Ready Queue&lt;/b&gt;: Ready상태에 있는 프로세스들을 모아놓은 Queue&lt;/li&gt;
&lt;/ul&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;CPU 디스패처(Dispatcher)&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;CPU 스케줄러에 의해 &lt;b&gt;선택된 프로세스를 CPU에 할당하는 역할&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;현재 Running 상태에 있는 프로세스와 스케줄러를 통해 선택된 프로세스를 &lt;b&gt;컨텍스트 스위칭(Context Switching)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;컨텍스트 스위칭이 이루어지는 커널 모드(Kernel Mode)와 유저 모드(User Mode)의 전환&lt;/li&gt;
&lt;li&gt;선택된 프로세스가 어디서 부터 실행될지 적절한 위치로 이동시키는 역할&lt;/li&gt;
&lt;/ol&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스케줄러의 선점 방식에는 &lt;b&gt;Nonpreemptive Scheduling&lt;/b&gt;, &lt;b&gt;preemptive Scheduling&lt;/b&gt;이 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Nonpreemptive Scheduling&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;프로세스가 자발적으로 Running상태를 벗어나고 다른 프로세스에게 점유권을 양보할 때를 말함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로세스가 Running 상태에서 Terminated, Ready, Waiting 상태로 옮겨가는 것은 &lt;br /&gt;&lt;b&gt;운영체제의 강제적인 개입 없이 진행될 수 있기 때문에&lt;/b&gt; 비선점 스케줄링이라고 불림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점: &lt;/b&gt;프로그램들의 자체적으로 협력적으로 일어날 수 있기 때문에 &lt;b&gt;Cooperative(협력적)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점: &lt;/b&gt;느린 응답성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Preemptive Scheduling&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;기본적으로 Nonpreemptive Scheudling의 역할을 포함하고 강제적으로 운영체제가 개입하는 상황이 추가됨
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Running 되고 있는 프로세스가 CPU의 Time-Slice시간을 모두 사용했다면, &lt;br /&gt;운영체제가 개입하여 Ready Queue에 해당 프로세스를 Ready 상태로 변경해야함&lt;/li&gt;
&lt;li&gt;우선순위에 따라서 Running되는 프로세스를 강제적으로 Ready 상태로 바꾸는 스케줄러의 개입&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: 적극적, 강제적, 빠른 응답성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;: 데이터 일관성 이슈&lt;/li&gt;
&lt;/ul&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;h4 data-ke-size=&quot;size20&quot;&gt;FCFS(First-Come, First-Served)&lt;/h4&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;기존 Queue와 동일한 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SJF(Shortest-Job-First)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로세스의 다음 CPU Burst가 가장 짧은 프로세스부터 차례로 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SRTF(Shortest-Remaining-Time-First)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;남은 CPU Burst가 가장 짧은 프로세스부터 실행&lt;/li&gt;
&lt;li&gt;SJF를 실행하는 동안 더 짧은 새로운 프로세스가 들어올 것을 대비한 알고리즘&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Priority&lt;/h4&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;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;RR(Round-Robin)&lt;/h4&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;Time-Slice로 나누어진 CPU 시간을 번갈아가면서 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Multilevel Queue&lt;/h4&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;/ul&gt;</description>
      <category>CS/운영체제</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/32</guid>
      <comments>https://eung7.tistory.com/32#entry32comment</comments>
      <pubDate>Tue, 23 Apr 2024 17:55:06 +0900</pubDate>
    </item>
    <item>
      <title>스레드 갯수를 정하는 방법(CPU bound, IO bound)</title>
      <link>https://eung7.tistory.com/31</link>
      <description>&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;Burst&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;&lt;b&gt;CPU Burst&lt;/b&gt;: 프로세스가 CPU에서 한 번에 연속적으로 실행되는 시간&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;IO Burst&lt;/b&gt;: 프로세스가 IO작업을 요청하고 결과를 기다리는 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CPU bound 프로세스&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;CPU Burst가 다분한 프로세스&amp;nbsp;&lt;/li&gt;
&lt;li&gt;연산 작업이 많은 프로그램 (Ex.동영상 편집 프로그램, 머신러닝 프로그램)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IO bound 프로세스&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;IO Burst가 다분한 프로세스&lt;/li&gt;
&lt;li&gt;네트워크가 자주 사용되는 작업 (Ex.백엔드 API 서버)&lt;/li&gt;
&lt;/ul&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;CPU bound 프로그램에서 적절한 스레드의 개수&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;코어의 개수 + 1&lt;/b&gt;을 넘어가면 안 됨&amp;nbsp;&lt;/li&gt;
&lt;li&gt;예를 들어, 듀얼 코어 CPU에 CPU bound 프로그램을 동작할 때 스레드 몇 개를 할당하는 것이 가장 좋을까?&lt;/li&gt;
&lt;li&gt;만약 4개의 스레드가 2개씩 하나의 코어로 할당이 되면 아래와 같은 모습
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 코어는 &lt;b&gt;Thread&lt;/b&gt; &lt;b&gt;Context Switching&lt;/b&gt;을 할 때마다 CPU 리소스를 낭비&lt;/li&gt;
&lt;li&gt;따라서 많은 스레드를 둔다고 좋은 것만은 아님&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN8c3C/btsGQ5eAEzG/QkfIaKUxFemB7Vgbh2T4K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN8c3C/btsGQ5eAEzG/QkfIaKUxFemB7Vgbh2T4K1/img.png&quot; data-alt=&quot;프로세스에 4개의 스레드가 있을 때&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN8c3C/btsGQ5eAEzG/QkfIaKUxFemB7Vgbh2T4K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN8c3C%2FbtsGQ5eAEzG%2FQkfIaKUxFemB7Vgbh2T4K1%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;600&quot; height=&quot;571&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로세스에 4개의 스레드가 있을 때&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 2개의 스레드가 각 코어에 들어가면, 불필요한 Context Switching이 필요가 없어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDoeoV/btsGRJ27NKU/8WZhFckbFsCP2L6AEw5MfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDoeoV/btsGRJ27NKU/8WZhFckbFsCP2L6AEw5MfK/img.png&quot; data-alt=&quot;프로세스의 두 개의 스레드가 있을 때&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDoeoV/btsGRJ27NKU/8WZhFckbFsCP2L6AEw5MfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDoeoV%2FbtsGRJ27NKU%2F8WZhFckbFsCP2L6AEw5MfK%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;600&quot; height=&quot;416&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로세스의 두 개의 스레드가 있을 때&lt;/figcaption&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;IO bound 프로그램에서 적절한 스레드의 개수&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;/li&gt;
&lt;li&gt;기기 사양, 프로그램 특성을 고려하여 적절한 스레드 수를 찾아야함&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS/운영체제</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/31</guid>
      <comments>https://eung7.tistory.com/31#entry31comment</comments>
      <pubDate>Mon, 22 Apr 2024 20:43:07 +0900</pubDate>
    </item>
    <item>
      <title>컨텍스트 스위칭(Context Switching)</title>
      <link>https://eung7.tistory.com/30</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Context Switching(컨텍스트 스위칭)&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;CPU/코어에서 실행 중이던 프로세스/스레드가 다른 프로세스/스레드로 교체 되는 것&lt;/li&gt;
&lt;li&gt;여러 프로세스/스레드를 동시에 실행시키기 위해서 필요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컨텍스트(Context)&lt;/b&gt;: 프로세스/스레드의 상태(CPU, 메모리 등)&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;주어진 time slice(quantum)를 다 사용할 떄&lt;/li&gt;
&lt;li&gt;IO작업을 해야할 떄&lt;/li&gt;
&lt;li&gt;다른 리소스를 기다릴 떄&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OS 커널(Kernel)&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;b&gt;Context Switching을 실행&lt;/b&gt;하는 곳&lt;/li&gt;
&lt;li&gt;각종 리소스를 관리 및 감독하는 역할&lt;/li&gt;
&lt;/ul&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;Context Switching의 종류&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;Process Context Switching&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;같은 프로세스의 스레드들끼리 스위칭 &lt;b&gt;Thread Context Switching&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1825&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baYL5D/btsGNFs3tLK/puJFYIM0uebjEY5LBpt4ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baYL5D/btsGNFs3tLK/puJFYIM0uebjEY5LBpt4ok/img.png&quot; data-alt=&quot;CPU실행흐름에서 컴퓨터의 리소스가 필요할 때, 운영체제의 커널 모드가 작동&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baYL5D/btsGNFs3tLK/puJFYIM0uebjEY5LBpt4ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaYL5D%2FbtsGNFs3tLK%2FpuJFYIM0uebjEY5LBpt4ok%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;400&quot; height=&quot;365&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1825&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CPU실행흐름에서 컴퓨터의 리소스가 필요할 때, 운영체제의 커널 모드가 작동&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커널 모드에서 실행 &lt;br /&gt;*&lt;b&gt;커널 모드&lt;/b&gt;: 프로세스가 진행됨에 따라서 컴퓨터의 여러 리소스를 접근하기 위해서는 운영체제의 Kernel을 통해서 접근하는 모드&lt;/li&gt;
&lt;li&gt;CPU의 레지스터 상태를 교체 *레지스터: 각종 명령어들을 수행하기 위해 필요한 여러 데이터들을 저장하는 곳
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로세스가 교체 될 때마다 이전 프로세스의 상태 정보를 알고 있어야 함&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KLDy9/btsGLFH5A3V/9Q4CbpIg5GqQrysASNFwPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KLDy9/btsGLFH5A3V/9Q4CbpIg5GqQrysASNFwPk/img.png&quot; data-alt=&quot;Thread Context Switching 도식화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KLDy9/btsGLFH5A3V/9Q4CbpIg5GqQrysASNFwPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKLDy9%2FbtsGLFH5A3V%2F9Q4CbpIg5GqQrysASNFwPk%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;2000&quot; height=&quot;710&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Thread Context Switching 도식화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bY4HB1/btsGNFfvJPJ/cRKMooVtxTBsOgeQMYqaX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bY4HB1/btsGNFfvJPJ/cRKMooVtxTBsOgeQMYqaX1/img.png&quot; data-alt=&quot;Process Context Switching 도식화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bY4HB1/btsGNFfvJPJ/cRKMooVtxTBsOgeQMYqaX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbY4HB1%2FbtsGNFfvJPJ%2FcRKMooVtxTBsOgeQMYqaX1%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;2000&quot; height=&quot;676&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Process Context Switching 도식화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Thread Context Switching&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;메모리 주소 관련 처리를 하지 않기 때문에, Process Context Switching보다 속도가 훨씬 빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Process Context Switching&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;가상(Virtual) 메모리 주소 관련 처리를 추가로 수행 (MMU, TLB)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS/운영체제</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/30</guid>
      <comments>https://eung7.tistory.com/30#entry30comment</comments>
      <pubDate>Fri, 19 Apr 2024 18:27:20 +0900</pubDate>
    </item>
    <item>
      <title>프로세스와 스레드 (멀티 스레딩, 멀티 프로세싱)</title>
      <link>https://eung7.tistory.com/29</link>
      <description>&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;프로그램&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;/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;각각의 프로세스는 &lt;b&gt;독립된 메모리 공간&lt;/b&gt;을 할당 받는다.&lt;/li&gt;
&lt;li&gt;명령어들과 데이터를 가짐&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CPU(Central Processing Unit)&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;/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;프로세스가 CPU에서 실행되기 위해 대기하는 공간&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;I/O(Input/Output)&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;네트워크와 데이터를 주고 받는 것&lt;/li&gt;
&lt;li&gt;입출력 장치와 데이터를 주고 받는 것&lt;/li&gt;
&lt;/ul&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;단일 프로세스 시스템&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLP0ro/btsGMf15PQn/fn5lMAld6uG3EvdbSHmrdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLP0ro/btsGMf15PQn/fn5lMAld6uG3EvdbSHmrdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLP0ro/btsGMf15PQn/fn5lMAld6uG3EvdbSHmrdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLP0ro%2FbtsGMf15PQn%2Ffn5lMAld6uG3EvdbSHmrdk%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;600&quot; height=&quot;410&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1366&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;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;b&gt;단점&lt;/b&gt;: 실행 중에 있는 프로세스가 I/O작업 동안에는 CPU는 아무것도 하지 않음 &amp;rarr; CPU 사용률이 좋지 않음&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;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cy6zq1/btsGJmhz15M/qp4qr3Jz9ycxbIcKTmMbiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cy6zq1/btsGJmhz15M/qp4qr3Jz9ycxbIcKTmMbiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cy6zq1/btsGJmhz15M/qp4qr3Jz9ycxbIcKTmMbiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcy6zq1%2FbtsGJmhz15M%2Fqp4qr3Jz9ycxbIcKTmMbiK%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;600&quot; height=&quot;367&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1223&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;CPU 사용률을 극대화 시키는 데 목적&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;여러 개의 프로그램을 메모리에 대기시켜놓고 동시에 실행시키는 시스템&lt;/li&gt;
&lt;li&gt;I/O 작업이 발생하면 다른 프로세스가 CPU에서 번갈아가면서 실행됨&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;: CPU 사용 시간이 길어지면, 다른 프로세스는 계속 대기해야함&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;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b76sZa/btsGI4ByyrY/sgpRKXkkCtJs6lxkQ5FCa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b76sZa/btsGI4ByyrY/sgpRKXkkCtJs6lxkQ5FCa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b76sZa/btsGI4ByyrY/sgpRKXkkCtJs6lxkQ5FCa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb76sZa%2FbtsGI4ByyrY%2FsgpRKXkkCtJs6lxkQ5FCa0%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;600&quot; height=&quot;814&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;814&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;프로세스의 응답 시간을 최소화 시키는 데 목적&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;멀티 프로그래밍과 비슷하지만, CPU 타임을 아주 짧게 쪼개서 서로 다른 프로세스들이 번갈아 가면서 실행될 수 있다는 것이 차이&lt;/li&gt;
&lt;li&gt;번갈아 가면서 실행되는 속도가 매우 짧아서 마치 동시에 실행되는 효과를 볼 수 있음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&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;프로세스의 컨텍스트 스위칭(Context Switching)은 무거운 작업 &lt;br /&gt;*&lt;b&gt;컨텍스트 스위칭&lt;/b&gt;: CPU에서 어느 한 프로세스에서 다른 프로세스로 교체 되는 것&lt;/li&gt;
&lt;li&gt;프로세스는 각각 독립적인 메모리 공간을 차지하고 있어서, 프로세스끼리 데이터 공유가 어려움&lt;/li&gt;
&lt;li&gt;듀얼 코어의 등장으로 &lt;b&gt;스레드라는 개념이 필요&lt;/b&gt;하게 됨&lt;/li&gt;
&lt;/ul&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;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;CPU에서 실행되는 단위(Unit Of Execution)&lt;/li&gt;
&lt;li&gt;같은 프로세스의 스레드들끼리 Context Switching은 가벼운 작업&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;각 스레드들은 메모리 영역에서 스택 및 프로그램 카운터는 고유한 영역으로 치부됨 &lt;br /&gt;*&lt;b&gt;프로그램 카운터&lt;/b&gt;: 다음번에 실행되어야 할 명령어가 있는 메모리 주소를 가르키는 것&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;여러 프로세스와 여러 스레드가 아주 짧게 쪼개진 CPU Time을 나눠 갖는 것&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;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;902&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8d03h/btsGLts1fW3/Ksy3vEo46FEl6KRUiWJTPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8d03h/btsGLts1fW3/Ksy3vEo46FEl6KRUiWJTPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8d03h/btsGLts1fW3/Ksy3vEo46FEl6KRUiWJTPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8d03h%2FbtsGLts1fW3%2FKsy3vEo46FEl6KRUiWJTPk%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;600&quot; height=&quot;271&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;902&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 개 이상의 프로세서나 코어를 활용하는 시스템&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS/운영체제</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/29</guid>
      <comments>https://eung7.tistory.com/29#entry29comment</comments>
      <pubDate>Fri, 19 Apr 2024 11:18:51 +0900</pubDate>
    </item>
    <item>
      <title>AppBundle을 통해 앱을 구성하는 파일 알아보기</title>
      <link>https://eung7.tistory.com/25</link>
      <description>&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;/li&gt;
&lt;li&gt;문제가 발생했을 떄 유연하게 대처 가능&lt;/li&gt;
&lt;li&gt;앱의 구성 파일은 크게 &lt;b&gt;.xcarchive, .dSYM, .app, info.plist&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;.xcarchive&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;앱 배포를 위해 App Archiving을 실행하면 나오는 빌드 결과물&lt;/li&gt;
&lt;li&gt;이 파일의 패키지 내용 보기를 하면 어떤 파일로 구성되어 있는지 확인 가능&lt;/li&gt;
&lt;li&gt;패키지 파일로는 .dSYM&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1003&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6LxAQ/btsGAN0IISo/KHVnznncIFtee9dIvVD7l1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6LxAQ/btsGAN0IISo/KHVnznncIFtee9dIvVD7l1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6LxAQ/btsGAN0IISo/KHVnznncIFtee9dIvVD7l1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6LxAQ%2FbtsGAN0IISo%2FKHVnznncIFtee9dIvVD7l1%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;2000&quot; height=&quot;1003&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1003&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Archive로 들어가서 구성된 파일을 보고 싶은 버전을 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVJouB/btsGCsOkelM/9jjXpS3mTdAcrtgJPmQWM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVJouB/btsGCsOkelM/9jjXpS3mTdAcrtgJPmQWM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVJouB/btsGCsOkelM/9jjXpS3mTdAcrtgJPmQWM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVJouB%2FbtsGCsOkelM%2F9jjXpS3mTdAcrtgJPmQWM1%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;2000&quot; height=&quot;1389&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1389&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오른쪽 버튼을 클릭해서 Show in Finder를 클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;2596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cA9WYv/btsGAKJJSxx/FtZ49l8H2uIN594Bjp2Gf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cA9WYv/btsGAKJJSxx/FtZ49l8H2uIN594Bjp2Gf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cA9WYv/btsGAKJJSxx/FtZ49l8H2uIN594Bjp2Gf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcA9WYv%2FbtsGAKJJSxx%2FFtZ49l8H2uIN594Bjp2Gf0%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;350&quot; height=&quot;2596&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;2596&quot;/&gt;&lt;/span&gt;&lt;/figure&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;b&gt;Show Package Contents(패키지 내용 보기)&lt;/b&gt;클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkmPiV/btsGBvFbIxd/45K7p9nDkL84u9Se19Ub10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkmPiV/btsGBvFbIxd/45K7p9nDkL84u9Se19Ub10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkmPiV/btsGBvFbIxd/45K7p9nDkL84u9Se19Ub10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkmPiV%2FbtsGBvFbIxd%2F45K7p9nDkL84u9Se19Ub10%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;2000&quot; height=&quot;1452&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1452&quot;/&gt;&lt;/span&gt;&lt;/figure&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;/ul&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;.dSYM&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDtGYU/btsGBsBLamu/iIRAi63xMHHFJMD7VX7xI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDtGYU/btsGBsBLamu/iIRAi63xMHHFJMD7VX7xI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDtGYU/btsGBsBLamu/iIRAi63xMHHFJMD7VX7xI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDtGYU%2FbtsGBsBLamu%2FiIRAi63xMHHFJMD7VX7xI0%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;2000&quot; height=&quot;1357&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;/&gt;&lt;/span&gt;&lt;/figure&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;b&gt;Dynamic Symbol&lt;/b&gt;의 약자&lt;/li&gt;
&lt;li&gt;개발자가 추론할 수 없는 메모리 주소들을 우리가 읽을 수 있는 Symbol로서 변환&lt;/li&gt;
&lt;/ul&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;.app&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhgsmI/btsGBbmGRyG/yuWQ6JjXiPCPXYG5NhMjc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhgsmI/btsGBbmGRyG/yuWQ6JjXiPCPXYG5NhMjc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhgsmI/btsGBbmGRyG/yuWQ6JjXiPCPXYG5NhMjc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhgsmI%2FbtsGBbmGRyG%2FyuWQ6JjXiPCPXYG5NhMjc0%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;2000&quot; height=&quot;1357&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Products &amp;rarr; Applications &amp;rarr; 앱 아이콘을 오른쪽 클릭 &amp;rarr; Show Package Contents(패키지 내용 보기)클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kWb8P/btsGAexu5ZL/dThpnYroopmYCOk1PWOq41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kWb8P/btsGAexu5ZL/dThpnYroopmYCOk1PWOq41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kWb8P/btsGAexu5ZL/dThpnYroopmYCOk1PWOq41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkWb8P%2FbtsGAexu5ZL%2FdThpnYroopmYCOk1PWOq41%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;2000&quot; height=&quot;1357&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패키지 내용에는 메타데이터, Assets, Provision 파일, 바이너리 등이 포함&lt;/li&gt;
&lt;/ul&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;info.plist&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtL0f7/btsGCx9UIgQ/blah92SHK5RO7fUicnb441/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtL0f7/btsGCx9UIgQ/blah92SHK5RO7fUicnb441/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtL0f7/btsGCx9UIgQ/blah92SHK5RO7fUicnb441/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtL0f7%2FbtsGCx9UIgQ%2Fblah92SHK5RO7fUicnb441%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;2000&quot; height=&quot;1357&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;앱의 메타데이터로 존재하는 info.plist가 존재&lt;/li&gt;
&lt;li&gt;XCode에서 변경되는 info.plist는 사실 이렇게 아카이빙되어서 어플리케이션으로 동작&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>iOS/XCode</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/25</guid>
      <comments>https://eung7.tistory.com/25#entry25comment</comments>
      <pubDate>Sat, 13 Apr 2024 17:11:59 +0900</pubDate>
    </item>
    <item>
      <title>XCode Build Phase로 빌드 과정 알아보기</title>
      <link>https://eung7.tistory.com/24</link>
      <description>&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;XCode는 명령어들의 집합&lt;/li&gt;
&lt;li&gt;명령어들이 어떤 순서로 어떻게 실행되는지에 대한 것이 Build Phase&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q3T2D/btsGBXHXXIf/yRTTxI3IsCVJSTQPhlwzGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q3T2D/btsGBXHXXIf/yRTTxI3IsCVJSTQPhlwzGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q3T2D/btsGBXHXXIf/yRTTxI3IsCVJSTQPhlwzGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq3T2D%2FbtsGBXHXXIf%2FyRTTxI3IsCVJSTQPhlwzGk%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;2000&quot; height=&quot;1449&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TARGETS &amp;rarr; Build Phases로 이동&lt;/li&gt;
&lt;li&gt;Build가 되면, &lt;b&gt;Target Dependencies&lt;/b&gt;부터 &lt;b&gt;Copy Bundle Resources&lt;/b&gt;까지 순서대로 Build를 진행&lt;/li&gt;
&lt;/ul&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;Target Dependencies&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1F1IE/btsGzM81oTH/hgjOqQGrpQKNm3wcWFAz6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1F1IE/btsGzM81oTH/hgjOqQGrpQKNm3wcWFAz6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1F1IE/btsGzM81oTH/hgjOqQGrpQKNm3wcWFAz6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1F1IE%2FbtsGzM81oTH%2FhgjOqQGrpQKNm3wcWFAz6K%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;2000&quot; height=&quot;1449&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;/&gt;&lt;/span&gt;&lt;/figure&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;SPM이나 Pods로 추가된 외부 라이브러리 및 Apple 프레임워크는 Target Dependencies에 명시적으로 추가하지 않아도 됨 &amp;rarr; 프레임워크를 추가할 때, 알아서 종속성을 관리해 줌&lt;/li&gt;
&lt;/ul&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;Run Build Tool Plug-ins&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;/ul&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;Compile Sources&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XKYJI/btsGBgnGfFQ/RqtuHr9s9B4boS7vjjUm01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XKYJI/btsGBgnGfFQ/RqtuHr9s9B4boS7vjjUm01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XKYJI/btsGBgnGfFQ/RqtuHr9s9B4boS7vjjUm01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXKYJI%2FbtsGBgnGfFQ%2FRqtuHr9s9B4boS7vjjUm01%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;2000&quot; height=&quot;1449&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;/&gt;&lt;/span&gt;&lt;/figure&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;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7aYcW/btsGAZ7BMNA/ggssD9rRLbxWqY9NyBLzk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7aYcW/btsGAZ7BMNA/ggssD9rRLbxWqY9NyBLzk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7aYcW/btsGAZ7BMNA/ggssD9rRLbxWqY9NyBLzk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7aYcW%2FbtsGAZ7BMNA%2FggssD9rRLbxWqY9NyBLzk1%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;2000&quot; height=&quot;1436&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 파일에 Compiler Flags에 컴파일 조건을 걸 수 있음&lt;/li&gt;
&lt;li&gt;예를 들어 Objective-C에서 ARC를 MRC로 사용할 수 있음&lt;/li&gt;
&lt;/ul&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;Link Binary With Libraries&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn0rsI/btsGBOLeNn8/pOrfDOdYppm9LgODaDfpCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn0rsI/btsGBOLeNn8/pOrfDOdYppm9LgODaDfpCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn0rsI/btsGBOLeNn8/pOrfDOdYppm9LgODaDfpCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn0rsI%2FbtsGBOLeNn8%2FpOrfDOdYppm9LgODaDfpCk%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;2000&quot; height=&quot;1449&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;/&gt;&lt;/span&gt;&lt;/figure&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;Target Dependencies와는 달리 SPM 및 Pods로 등록한 라이브러리를 등록해야함&lt;/li&gt;
&lt;/ul&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;Copy Bundle Resources&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7acXT/btsGAexpiRx/EGn2fnnkjU09oSvzn0mHl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7acXT/btsGAexpiRx/EGn2fnnkjU09oSvzn0mHl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7acXT/btsGAexpiRx/EGn2fnnkjU09oSvzn0mHl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7acXT%2FbtsGAexpiRx%2FEGn2fnnkjU09oSvzn0mHl1%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;2000&quot; height=&quot;1449&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;App Bundle에 복사할 코드외의 리소스 파일을 지정&lt;/li&gt;
&lt;li&gt;일반적으로 앱에서 사용되는 이미지, 사운드, 폰트, String파일 등이 사용&lt;/li&gt;
&lt;li&gt;기본적으로 제공되는 StoryBoard, XCAssets이 여기에 포함&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>iOS/XCode</category>
      <author>Eung7</author>
      <guid isPermaLink="true">https://eung7.tistory.com/24</guid>
      <comments>https://eung7.tistory.com/24#entry24comment</comments>
      <pubDate>Sat, 13 Apr 2024 11:43:47 +0900</pubDate>
    </item>
  </channel>
</rss>