ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

ios-og


๐Ÿ“ฑ [์Šคํƒ ํฌ๋“œ] iOS ๊ฐ•์˜ ํ•™์Šตํ•˜๊ธฐ (CS193p by Paul Hegarty in Stanford)

  • ์Šคํƒ ํฌ๋“œ์˜ Paul Hegarty ๊ต์ˆ˜๋‹˜๊ป˜์„œ ์ง„ํ–‰ํ•˜์‹  CS193p ๊ฐ•์˜๋ฅผ ํ†ตํ•ด iOS์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ๊ธฐ์ดˆ๋ฅผ ์•Œ์•„๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๋ธ”๋กœ๊ทธ์—๋Š” ๊ฐ•์˜ ๋‹จ์œ„๋กœ ์—…๋กœ๋“œํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ๊ฐ•์˜ ๋‚ด์šฉ์„ ํ•„๊ธฐํ•˜๋Š” ๋ธ”๋กœ๊น…์ด ์•„๋‹ˆ๋ผ ์ถ”๊ฐ€์ ์ธ ์ž๋ฃŒ ์กฐ์‚ฌ๋‚˜ ๋‹ค๋ฅธ ๊ฐ•์˜ ๋‚ด์šฉ์—์„œ ์Šต๋“ํ•œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ํ˜•์‹์˜ ๋ธ”๋กœ๊ทธ๊ฐ€ ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๐ŸŽฏ Lecture.01 Introduction

  • iOS์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ์„ค๋ช…๊ณผ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์„ค๋ช…์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์‹ค์Šตํ•ด๋ณธ git Repository

๐Ÿ“ Swift ์–ธ์–ด์˜ ํŠน์ง•

  • Swift๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Object Oriented Prograaming)์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ํ•จ์ˆ˜ ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Function Oriented Programming), ํ”„๋กœํ† ์ฝœ ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Protocol Oriented Programming) ์—ญ์‹œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ iOS์˜ ๊ตฌ์กฐ

  • iOS๋Š” ํฌ๊ฒŒ 4๊ฐ€์ง€์˜ ๊ตฌ์กฐ๋กœ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

    Cocoa Touch

    Media

    Core Services

    Core OS

    ์•„๋ž˜๋กœ ๊ฐˆ์ˆ˜๋ก ์‹œ์Šคํ…œ์— ๊ฐ€๊น๊ณ  ์œ„๋กœ ์˜ฌ๋ผ๊ฐˆ์ˆ˜๋ก ์‚ฌ์šฉ์ž์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.

    1. Core OS:

      iOS์˜ Core OS๋Š” BSD ๊ณ„์—ด Unix๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ ์†์— ์ผ์–ด๋‚˜๋Š” ๋ชจ๋“  ์ผ๋“ค์€ C์–ธ์–ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

      BSD Unix

    2. Core Services:

      ์ด ์ธต์€ ์•„๋ž˜์˜ ํ•˜์œ„ ์„œ๋น„์Šค๋“ค์˜ ์ตœ์ƒ์œ„์— ์žˆ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์ธต์ž…๋‹ˆ๋‹ค.

      ์Šค๋งˆํŠธํฐ์˜ ํ˜„์žฌ ์œ„์น˜ ๋ฐฉํ–ฅ์„ ์ฐพ๊ณ  ์‹œ์Šคํ…œ ํŒŒ์ผ์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ด Core Service๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    3. Media:

      ์•„์ดํฐ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์•„์ดํŒŸ์— ์ „ํ™” ๊ธฐ๋Šฅ์„ ๋„ฃ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ Media๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ณ„์ธต์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

    4. Cocoa Touch:

      ์ด ๊ณ„์ธต์€ iOS์˜ UI ์ธต(Layer) ์ž…๋‹ˆ๋‹ค. ๋ฒ„ํŠผ๊ณผ ์Šฌ๋ผ์ด๋” ๊ฐ™์€ UI ์š”์†Œ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“ Design Strategy

  • ๊ต์ˆ˜๋‹˜์˜ ๊ธฐ์กด ์ˆ˜์—…์—์„œ๋Š” MVC(Model-View-Controller)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ•์˜ํ•˜์…จ์Šต๋‹ˆ๋‹ค. ๋””์ž์ธ ์ „๋žต์€ ์˜ต์…˜์ด ์•„๋‹ˆ๋ผ ๋ฐ˜๋“œ์‹œ ์ง€์ผœ์•ผํ•˜๋Š” ๊ทœ์ •์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ 2020๋…„ Spring ์ˆ˜์—… ๊ธฐ์ค€์œผ๋กœ MVVM(Model-View-ViewModel)์„ ๊ฐ•์˜ํ•ด์ฃผ์‹ญ๋‹ˆ๋‹ค. ์ˆ˜์—…์—์„œ MVC๋ฅผ "the old-style iOS development mechanism uses"(์˜ˆ์ „์— ์‚ฌ์šฉ๋œ iOS ๊ฐœ๋ฐœ ์Šคํƒ€์ผ)๋กœ ๊ทœ์ •ํ•˜์…”์„œ MVVM์„ ๊ฐ•์˜ํ•˜์‹œ์ง€๋งŒ ํ•™์Šต์ž์— ์ž…์žฅ์—์„œ iOS ์ƒํƒœ๊ณ„์—์„œ ์‚ฌ์šฉ๋˜๋Š” MVC์™€ MVVM์„ ๋ชจ๋‘ ์•Œ๊ณ  ์‹ถ์–ด ๋‘ ๋‚ด์šฉ ๋‹ค ํ•™์Šตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๐ŸŽด ์ง ๋งž์ถ”๊ธฐ ๊ฒŒ์ž„ ๋งŒ๋“ค๊ธฐ(Making Concentration Game)

  • ์ง ๋งž์ถ”๊ธฐ ๊ฒŒ์ž„์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŒŒ์ผ์ด ์žˆ์ง€๋งŒ ์—ฌ๊ธฐ์„œ๋Š” 2๊ฐœ์˜ ํŒŒ์ผ๋งŒ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Assets ํด๋”๋Š” ์•ฑ์˜ ์•„์ด์ฝ˜ ์ด๋ฏธ์ง€๋ฅผ ํฌํ•จํ•ด์„œ ์•„์ง ์„ค์ •ํ•˜์ง€ ์•Š์€ ์ด๋ฏธ์ง€๋“ค์˜ ๋ชจ์Œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„์ง ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ AppDelegate๋‚˜ LaunchScreen ์—ญ์‹œ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    ๊ทธ๋ž˜์„œ ํ•„์š”์—†๋Š” ํŒŒ์ผ๋“ค์„ ๋ธ”๋Ÿญ์ง€์ •ํ•ด ์šฐํด๋ฆญ์„ ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ต์…˜์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

    ๋นจ๊ฐ„ ๋ฐ•์Šค์˜ ์˜ต์…˜์„ ํด๋ฆญํ•˜๋ฉด ์ž๋™์ ์œผ๋กœ ํ•˜๋‚˜์˜ Folder์•ˆ์— ๋ฌถ์–ด์ฃผ๊ณ  ๊ทธ ์ด๋ฆ„์„ Supporting Files๋กœ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • Main.storyboard์— ๋“ค์–ด๊ฐ€๋ฉด ์ง์ ‘ ํ™”๋ฉด์„ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๊ณ , ๊ทธ๋ฆฐ ๊ฒฐ๊ณผ๋ฌผ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž˜ ๋ชฐ๋ž๋˜ ๋ถ€๋ถ„์€ ์•„๋ž˜์˜ Appearance ์˜€์Šต๋‹ˆ๋‹ค.

    Device: ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•  ๊ธฐ๊ธฐ์˜ ์ข…๋ฅ˜(e.g. iPad Pro, iPhone 12 etc)

    Appearance: Dark/Light Mode์—์„œ ๊ฒฐ๊ณผ๋ฌผ ์ถœ๋ ฅ

    Orientation: ๊ฐ€๋กœ/์„ธ๋กœ ๋ชจ๋“œ

    ๋‹คํฌ๋ชจ๋“œ๊ฐ€ ๋‚˜์˜ค๊ธฐ ์ „(iOS 13 ์ด์ „)์—๋Š” ํ•ด๋‹น ์„ ํƒ์ง€๊ฐ€ ์•„์˜ˆ ์—†์—ˆ๊ณ  ์ฒ˜์Œ ๋‚˜์™”์„ ๋•Œ์—๋„ Xcode์—์„œ Interface Style๋กœ ํ‘œ๊ธฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ์Šคํ† ๋ฆฌ๋ณด๋“œ์— Button์„ ์ถ”๊ฐ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    Button์˜ ์ƒ‰๊น”์„ ๋ฐ”๊พธ๋Š” ๋“ฑ Button์˜ ํŠน์„ฑ์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Utility's Pane์—์„œ ์„ค์ •์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ ๋ณ€๊ฒฝ์„ ์œ„ํ•œ UI์ธ Utility's Pane์€ ๊ฐ์ฒด ์ง€ํ–ฅ์ ์œผ๋กœ ๊ตฌํ˜„ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

    ์•„๋ž˜ ํŒŒ๋ž€์ƒ‰ ๋ฐ•์Šค์—๋Š” Control Pane์ด ๋ณด์ด๋Š”๋ฐ, ๋ฒ„ํŠผ์€ Control์„ ์ƒ์†๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— Control Pane์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

    ์—ฌ๊ธฐ์— ๋”ํ•ด Control Pane ์•„๋ž˜์—๋Š” View Pane์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

    Control์€ View๋ฅผ ์ƒ์†๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— Button์— View UI๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌ์กฐ์ ์œผ๋กœ ๋ณด๋ฉด

    class Button: Control
    class Control: View

    ๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • ๊ตฌํ˜„์ด ์™„๋ฃŒ๋œ ์ด๋ฏธ์ง€์— ๋™์ž‘์„ ์„ค์ •ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ๋Š” Swift์˜ ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ViewController ํŒŒ์ผ์„ ์—ด์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ธํŒ…๋˜์–ด์žˆ๋Š” ์ฝ”๋“œ๋Š” ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์‚ญ์ œํ–ˆ์Šต๋‹ˆ๋‹ค.

    • UIKit: Button, Slider ๋“ฑ UI์™€ ๊ด€๋ จ๋œ ์†Œ์Šค๋“ค์ด ์žˆ๋Š” iOS ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.
    • ViewController: ์ด ํด๋ž˜์Šค์˜ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์—ฌ๊ธฐ๋งŒ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ UI์— ์žˆ๋Š” ์š”์†Œ๋“ค์˜ ์ด๋ฆ„๋„ ๋ณ€๊ฒฝํ•ด์ฃผ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๊พธ์ง€ ์•Š๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ํด๋ž˜์Šค๋Š” UIViewController๋ฅผ ์ƒ์†๋ฐ›๋Š” subclass์ž…๋‹ˆ๋‹ค.
  • storyboard์—์„œ ์š”์†Œ๋ฅผ ํด๋ฆญํ•œ ํ›„ control์„ ๋ˆ„๋ฅธ ์ƒํƒœ๋กœ ์ฝ”๋“œ์— ๊ฐ€์ ธ๊ฐ€๋ฉด ๋ฐ”๋กœ ์—ฐ๊ฒฐ๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Swift๊ฐ€ ๋‹ค๋ฅธ ์–ธ์–ด๋“ค๊ณผ ๋‹ค๋ฅธ ํŠน์ง•

    1. ๋ชจ๋“  ์ธ์ˆ˜์— ์ด๋ฆ„์ด ์žˆ์Šต๋‹ˆ๋‹ค(every argument has a name). ๋ฉ”์†Œ๋“œ๋ฅผ ๋ถ€๋ฅผ ๋•Œ ์ด ์ด๋ฆ„์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    2. ์ธ์ˆ˜๋“ค์ด 2๊ฐœ์˜ ์ด๋ฆ„์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ํ˜ธ์ถœ์‹œ ์‚ฌ์šฉํ•˜๋Š” ์™ธ๋ถ€(external) ์ด๋ฆ„์ด๊ณ , ํ•˜๋‚˜๋Š” ๋กœ์ง ๋‚ด๋ถ€์—์„œ ๊ตฌํ˜„์— ์‚ฌ์šฉํ•  ๋‚ด๋ถ€(internal) ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • ์—ฐ๊ฒฐ์ด ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณด๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ์•ˆ์— ์ฝ˜์†”์— ์ถœ๋ ฅ์ด ๋  ๋ฉ”์„ธ์ง€๋ฅผ ๋„ฃ์Šต๋‹ˆ๋‹ค.

    UIButton์ธ ์˜ค๋ฅธ์ชฝ์˜ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ํ•จ์ˆ˜ touchCard์˜ parameter๋กœ ๊ทธ ์ž…๋ ฅ์ด ๋“ค์–ด๊ฐ€๊ฒŒ๋˜๊ณ  ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œ์ผœ์ค๋‹ˆ๋‹ค. ์ด์ œ ์ฝ˜์†”์˜ ์ถœ๋ ฅ๋ฌธ์„ ์ง€์šฐ๊ณ  ์นด๋“œ๋ฅผ ๋’ค์ง‘์–ด์ค„ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ, ๋„ค์ด๋ฐ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ "์˜์–ด์ฒ˜๋Ÿผ ์ฝํžˆ๋Š” ๊ฒƒ" ์ž…๋‹ˆ๋‹ค. flipCard๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

    ํ•จ์ˆ˜ flipCard์˜ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ณ€์ˆ˜ ๋ช…์€ emoji์™€ button์ด๊ณ , ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ž…๋ ฅ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์€ withEmoji, on ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด flipCard withEmoji "ghost" on sender๋ผ๋Š” ์˜์–ด๋ฌธ์žฅ์œผ๋กœ ์ฝํž ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ ๋„ค์ด๋ฐ์ด ์™„์„ฑ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ touchCard์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” sender ์•ž์— under bar(_)๊ฐ€ ๋ถ™์–ด์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Š” ์™ธ๋ถ€ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Swift์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ๋ณ€์ˆ˜๋ช…์„ ์ƒ๋žตํ•ด์ฃผ๋Š” ๊ฒฝ์šฐ๋Š” ํ”์น˜ ์•Š์€๋ฐ, ๊ทธ ์ด์œ ๋Š” ์ด๋Ÿฌํ•œ ๋กœ์ง์ด Objective-C์—์„œ ์™”๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” iOS์—์„œ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์ธ๋ฐ ์ด๊ฒƒ์€ Objective-C์—์„œ ์™”๊ณ  Objective-C๋Š” ๋‚ด๋ถ€/์™ธ๋ถ€ ์ด๋ฆ„์˜ ๊ฐœ๋…์ด ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. flipCard ๋ฉ”์†Œ๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    ์ฒซ๋ฒˆ์งธ ์กฐ๊ฑด์ ˆ์€ ๋ฒ„ํŠผ์˜ ํ˜„์žฌ ํƒ€์ดํ‹€์ด ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ฐ’์ด๋ผ๋ฉด ๋ฒ„ํŠผ์„ ๋น„์–ด์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ์ด ๋•Œ, setTitle ์•ˆ์— for์˜ ๊ฐ’์œผ๋กœ ๋„ฃ์–ด์ฃผ๋Š” UIControl์ด ์ง€๊ธˆ์€ UIControl.State.normal์ด์ง€๋งŒ ์˜ˆ์ „ ๊ธฐ์ค€์œผ๋กœ๋Š” UIControlState.normal์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ State๋ฅผ ํ”„๋กœํผํ‹ฐ ๋“ฑ์œผ๋กœ ๋‹ค์‹œ ์„ ์–ธํ•ด์ฃผ๋Š” ๊ตฌ์กฐ๋กœ ๋ฐ”๋€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฐ‘์˜ else ๊ตฌ๋ฌธ์€ ๋ฐ˜๋Œ€๋กœ ํ˜„์žฌ ๋ฒ„ํŠผ์ด ํ•ด๋‹น ์ด๋ชจ์ง€๊ฐ€ ์•„๋‹ ๋•Œ ์ด๋ชจ์ง€๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ๊ฒฝ ์ƒ‰๊น”์„ ๋ฐ”๊ฟ€ ๋•Œ ์˜ค๋ฅธ์ชฝ์— ๋ณด์ด๋Š” ์ƒ‰๊น” ๋ฐ•์Šค๋Š” Color Literal๋กœ ๋ฐ”๋กœ ์ƒ‰๊น”์„ ์ง€์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ด์ œ ์ถ”๊ฐ€์ ์œผ๋กœ ๋‹ค๋ฅธ ๊ทธ๋ฆผ์˜ ์นด๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    ํ˜ธ๋ฐ• ๊ทธ๋ฆผ์„ ๋ณต์‚ฌ ๋ถ™์—ฌ๋„ฃ๊ธฐ๋กœ ์ถ”๊ฐ€ํ•œ ํ›„, touchSecondCard๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์œ ๋ น ๊ทธ๋ฆผ์€ ์—ฌ์ „ํžˆ ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ ํ˜ธ๋ฐ• ๊ทธ๋ฆผ์€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๊ทธ๋Ÿฐ์ง€ ์‚ดํŽด๋ณด๊ธฐ ์œ„ํ•ด, 22๋ฒˆ์งธ์ค„์— print๊ตฌ๋ฌธ์„ ๋„ฃ์–ด emoji๋ฅผ ์ถœ๋ ฅํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ ํ˜ธ๋ฐ• ์นด๋“œ๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ˜ธ๋ฐ• ์ด๋ชจ์ง€๋Š” ์ž˜ ์ถœ๋ ฅ์ด ๋˜์ง€๋งŒ ๊ฑฐ๊ธฐ์— ๋”ํ•ด ๋ˆ„๋ฅธ์  ์—†๋Š” ์œ ๋ น ์ด๋ชจ์ง€๋„ ๊ฐ™์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ํ˜ธ๋ฐ• ์นด๋“œ๋ฅผ 2๋ฒˆ ๋ˆŒ๋ €์„ ๋•Œ ์ถœ๋ ฅ์ž…๋‹ˆ๋‹ค.

    ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ์ด์œ ๋Š” ํ˜ธ๋ฐ• ์นด๋“œ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์œ ๋ น ์นด๋“œ๋ฅผ ๋ณต์‚ฌํ•ด์„œ ๋ถ™์—ฌ๋„ฃ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์œ ๋ น์„ ๋ณต์‚ฌํ•  ๋•Œ ์ € ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค๋Š” ์‚ฌ์‹ค ์—ญ์‹œ ๋ณต์‚ฌ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ์ž…๋‹ˆ๋‹ค. ํ˜ธ๋ฐ• ๊ทธ๋ฆผ์— ๋งˆ์šฐ์Šค ์šฐํด๋ฆญ์„ ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

    Touch Up Inside๋ฅผ ๋ณด๋ฉด ๋‘ ๋ฉ”์†Œ๋“œ ๋ชจ๋‘ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ x๋ฒ„ํŠผ์œผ๋กœ touchCard๋งŒ ์‚ญ์ œํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ touchSecondCard๋งŒ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


    • ๋‹ค์Œ์œผ๋กœ๋Š” ์นด๋“œ๋ฅผ ๋ช‡๋ฒˆ ๋’ค์ง‘์—ˆ๋Š”์ง€ ์ˆซ์ž๋ฅผ ์นด์šดํŠธํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์นด๋“œ ๋’ค์ง‘๊ธฐ ๊ฒŒ์ž„์€ ์นด๋“œ๋ฅผ ์ ๊ฒŒ ๋’ค์ง‘์„ ์ˆ˜๋ก ๋†’์€ ์ ์ˆ˜๋ฅผ ๋ฐ›๋Š” ๊ฒŒ์ž„์ž…๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ ์นด์šดํŠธํ•˜๊ธฐ ์œ„ํ•ด ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

      ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•œ ๋’ค, ์ด๋ฅผ ํ™”๋ฉด์— ๋ณด์—ฌ์ค„ Label์„ ๋งŒ๋“ค๊ณ  ์•„๊นŒ์™€ ๊ฐ™์ด ์ปจํŠธ๋กค ํ‚ค๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ์œ„์—์„œ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•„์š”ํ•ด์„œ Action์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ค€ ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ Outlet์ด๋ผ๋Š” ๊ธฐ๋Šฅ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š”๋ฐ, ์•„์šธ๋ ›์€ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

      Swift์—์„œ๋Š” ๋Š๋‚Œํ‘œ(!)๊ฐ€ ๋ถ™์œผ๋ฉด side effect๊ฐ€ ์žˆ๋Š”๋ฐ ์ดˆ๊ธฐํ™”ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ„์— flipCount๋Š” 0์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•˜์ง€ ์•Š์œผ๋ฉด init Error๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ flipCountLabel์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด์ œ flipCount๊ฐ€ ๋ฐ”๋€”๋•Œ๋งˆ๋‹ค flipCountLabel์ด ์ถœ๋ ฅํ•˜๋Š” ๊ฐ’์„ ๋ฐ”๊พธ๋Š” ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

      ์œ„์˜ ๊ตฌํ˜„์€ ์ •์ƒ์ ์œผ๋กœ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ €๋Ÿฐ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ฒŒ๋˜๋ฉด ๊ฐ ๋ฉ”์†Œ๋“œ๋งˆ๋‹ค ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ๋ฐ˜๋ณตํ•ด์„œ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜น์€ flipCount์— ๋ณ€ํ™”๋ฅผ ์ฃผ๊ฑฐ๋‚˜ text์— ๋“ค์–ด๊ฐˆ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” refactoring์ด ์žˆ๋‹ค๋ฉด ๋ชจ๋“  ๋ฉ”์†Œ๋“œ์— ์ ‘๊ทผํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด didSet ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ didSet์„ Property Observer๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

      • Swift๋Š” ๊ฐ•ํ•œ ํƒ€์ž… ์ถ”๋ก  ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์ด ํ™•์‹คํ•˜๋‹ค๋ฉด ํƒ€์ž…์„ ๋ช…์‹œํ•ด์ฃผ์ง€ ์•Š๋Š” ์ˆ˜์ค€์ด ์•„๋‹ˆ๋ผ ์“ฐ์ง€ ๋ง์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

      • ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•ด์„œ ๋ถ™์—ฌ๋„ฃ๋Š”๋‹ค๋Š” ๊ฒƒ์€ ๋ญ”๊ฐ€๋ฅผ ์ž˜๋ชปํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.. ์ด๋Ÿด ๊ฒฝ์šฐ fixํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค!

      ์ด์ œ ๊ธฐ๋Šฅ์€ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ ๋ชจ๋“  ์นด๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋ฉด ์นด๋“œ๊ฐ€ ์ƒ๊ธธ๋•Œ๋งˆ๋‹ค ๋น„์Šทํ•œ ํ˜•์‹์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ๊ณ„์† ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ•˜๋‚˜์˜ ๋ฉ”์†Œ๋“œ์— ๋ชจ๋“  ์นด๋“œ๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

      ์œ„์˜ ํ•จ์ˆ˜์—์„œ ์œ ์ผํ•˜๊ฒŒ ๋ณ€ํ•˜๋Š” ๋ถ€๋ถ„์€ flipCard ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ๋•Œ withEmoji์— ๋“ค์–ด๊ฐ€๋Š” String ๊ฐ’์ด๊ณ  ์ด๋ฅผ ํ•œ๋ฒˆ์— ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด Array๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Array์— ๋ชจ๋“  ์ด๋ชจ์ง€๋ฅผ ๋„ฃ์–ด ๋†“๊ณ  ๊ด€๋ฆฌํ•˜๋ฉด Data-Driven ๊ตฌ์กฐ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ํ•œ๋ฒˆ ์นด๋“œ๋ฅผ ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

      ์ด๋ฒˆ์—๋Š” Outlet์ด ์•„๋‹Œ Outlet Collection์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Outlet Collection์€ UI์— ์žˆ๋Š” ๊ฒƒ๋“ค์˜ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค.

      ๊ฐ•์˜์—์„œ๋Š” cardButtons.index(of:)๋ฅผ ์‚ฌ์šฉํ•˜์‹œ์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€๊ฐ€ ๋œน๋‹ˆ๋‹ค. firstIndex๋กœ ๋ฐ”๊พธ๋ผ๋Š” ๋ฉ”์„ธ์ง€๊ฐ€ ๋‚˜์™€ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

      ์œ„์˜ ๊ทธ๋ฆผ์—์„œ 2๊ฐœ์˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์˜ค๋ฅ˜๋Š” cardNumber๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ let์œผ๋กœ ๋ฐ”๊พธ๋ผ๋Š” ๋ง์ž…๋‹ˆ๋‹ค. ์™œ ๋‹ค๋ฅธ ์–ธ์–ด์ฒ˜๋Ÿผ ์ƒ์ˆ˜๋ฅผ const๋กœ ํ‘œํ˜„ํ•˜์ง€ ์•Š์„๊นŒ์š”? ์ด๊ฒƒ์€ Swift์—์„œ ์ฝ”๋“œ๋Š” ์˜์–ด์ฒ˜๋Ÿผ ์ฝํ˜€์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. const cardNumber๋Š” ์˜์–ด๋กœ ์ฝํžˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค!

      ๋ชจ๋“  ์นด๋“œ๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๊ณ  Array๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑํ•ด์ฃผ๋ฉด ์ •์ƒ ์ž‘๋™ํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

    ํ•˜์ง€๋งŒ ์œ„์˜ ๊ตฌ์กฐ๋Š” ๋ถˆ์•ˆ์ •ํ•œ(fragile) ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ด๋ชจํ‹ฐ์ฝ˜์˜ ๊ฐœ์ˆ˜๋Š” UI์— ์žˆ๋Š” ๋ฒ„ํŠผ๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ด์•ผํ•˜๊ณ  ๋˜‘๊ฐ™์€ ๊ฒƒ์„ ๋‘๋ฒˆ์”ฉ ๋„ฃ์–ด์ฃผ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด MVC ๋ชจ๋ธ์„ ํ†ตํ•ด ์ด ๊ตฌ์กฐ๋ฅผ ๋ฐœ์ „์‹œํ‚ฌ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Reference: [Stanford CS193p by Paul Hegarty](

๋ฐ˜์‘ํ˜•
๋Œ“๊ธ€
๋ฐ˜์‘ํ˜•
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG more
ยซ   2024/11   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
๊ธ€ ๋ณด๊ด€ํ•จ