티스토리 뷰

Swift

[Swift] Structures and Classes

learner._.Kio 2021. 3. 8. 15:19

목차

  • Structures and Classes
  • Initializer Syntax
  • Value Types vs Reference Types
  • Nested Types




Structures and Classes

지금까지는 Apple이 제공한 형식을 사용했다. 필요한 형식을 직접 만들고자 할 때 필요한 것이 구조체와 클래스다.

Custom Data Type [=User Defined Type]

  • Enumeration
  • Structure
  • Class

Programming Paradigm

프로그래밍 언어는 언어마다 철학을 가지고 있고, 내부적인 규칙이나 구현방식에 차이가 있다. 이러한 것들을 프로그래밍 패러다임 (Programming Paradigm) 이라고 한다. 프로그래밍 언어가 다양한 만큼 프로그래밍 패러다임도 다양하다.

  • Swift - 멀티 패러다임 언어

Object-Oriented Programming (객체지향)

  • Object : 객체지향 프로그래밍에서 가장 중요한 것은 객체

    • 도로 위 자동차, 운전자 모두 객체
    • 프로그래밍에서 처리하는 모든 것들을 객체로 만들고 원하는 기능을 구현한다.
  • 추상화 : 객체가 가진 여러가지 요소 중에서 프로그래밍에서 처리할 요소들을 도출하는 과정

    • Student Management Progame
      • School
      • Class
      • Grade
    • Fitness Membership Program
      • Height
      • Weight
      • Registration Date
  • Class : 추상화의 결과를 코드로 표현한 것. 객체를 생성하기 위한 설계도

    • 속성 - 객체의 특징과 상태

    • 메서드 - 객체의 동작

    • Instance - Class를 통해 생성된 하나의 객체

      • 객체는 동일한 속성과 메서드를 가지지만, 속성에 저장된 값과 메서드 실행결과는 인스턴스마다 차이가 있다.
    • 객체지향 프로그래밍에서는 객체들이 상호작용(Interaction) 한다.

      • 다른 객체의 속성을 바꾸거나 메서드를 속성 == Sending Messages
      • Sender / Receiver
  • Structure : OOP에서는 새로운 형식을 만들 때 대부분 클래스로 구현, 비교적 작은 데이터를 저장하거나 값형식이 필요한 경우 구조체로 구현한다.

    • 구조체 역시 클래스와 마찬가지로 설계도이다.
    • 클래스와 달리 객체라고 부르지 않고 값이라고 부른다.
    • 다른 언어에서는 클래스에서 생성한 객체를 인스턴스라고 부르지만, Swift에서는 형식에 관계없이 모두 인스턴스라고 부른다.

Struct 선언

struct StructName {
    property
    method
    initializer
    subscript
}

//  property, method, initializer, subscript 처럼 구조체 안에 있는 것들은 member라고 부른다.

Struct 예시

/// 설계도
struct Person {
    var name: String
    var age: Int

    func speak() {
        print("Hello")
    }
}

// 인스턴스 생성
let p = Person(name: "Steve", age: 50)

// struct의 name과는 scope과 달라 상관없다.
let name = "Paul"
name

// 속성 접근
p.name // Steve
p.age // 50
p.speak() // Hello

Class 선언

Class ClassName {
    property
    method
    initializer
    deinitializer
    subscript
}

Class 예시

class Person {
    var name = "John Doe"
    var age = 0

    func speak() {
        print("Hello")
    }
}

// 인스턴스 생성
let p = Person()

// 속성 접근
p.name // John Doe
p.age // 0
p.speak() // Hello
  • 구조체와 클래스는 저장공간에 처리하는 방식의 차이
  • Struct
    • 구조체는 스택이라는 부르는 메모리 공간에 값을 저장. 값을 전달할때마다 복사본을 전달 = 값형식
    • 값형식의 구조체는 인스턴스가 속한 스코프가 종료되면 메모리에서 자동으로 제거
  • Class
    • 클래스는 힙이라는 부르는 공간에 값을 저장. 스택에는 힙에 저장되어 있는 값의 주소를 전달. 값을 전달하면 복사본을 전달하지 않고, 주소를 전달 = 참조형식
    • 클래스에서만 상속지원
    • 클래스는 스코프에 상관없이 레퍼런스 카운팅을 통해 메모리가 관리된다.




Initializer Syntax

Initializer(생성자) 선언

init(parameters) {
    statements // 속성초기화
}
// 초기화가 완료되지 않으면 컴파일 에러

Initializer 예시

let str = "123"
let num = Int(str)

class Position {
    var x: Double
    var y: Double

    init() {
        x = 0.0
        y = 0.0
    }
}
// 모든 속성을 초기화 하면 에러가 사라진다.
// 생성자는 속성초기화가 가장 중요하고 유일한 목적이다.
// 생성자 실행이 종료되는 시점에는 모든 속성에 초기값이 저장되어 있어야한다.
let str = "123"
let num = Int(str)

class Position {
    var x: Double
    var y: Double

    init() {
        x = 0.0
        y = 0.0
    }

    init(value: Double) {
        x = value
        y = value
    }
}

let a = Position()
a.x // 0
a.y // 0

let b = Position(value: 100)
b.x // 100
b.y // 100




Value Types vs Reference Types

  • Value Type

    • Structure
    • Enumeration
    • Tuple
  • Reference Type

    • Class
    • Closure

Value Types(Struct) vs Reference Types(Class)의 비교

struct PositionValue {
    var x = 0.0
    var y = 0.0
}

class PositionObject {
    var x = 0.0
    var y = 0.0
}
// 생성과 동시에 기본값 저장 - 기본생성자

var v = PositionValue()
var o = PositionObject()

var v2 = v
var o2 = o

v2.x = 12
v2.y = 34

v.x // 0
v.y // 0
v2.x // 12
v2.y // 34

// 구조체는 값형식으로, v2는 v의 복사본으로 v2에서 값을 바꿔도 v에는 아무런 변화가 없다.
// v2와 v는 서로 다른 메모리 공간

o2.x = 12
o2.y = 34

o.x // 12
o.y // 34
o2.x // 12
o2.y // 34
// 클래스는 새로운 복사본을 생성하지 않고 원본(참조)을 전달하기 때문에 어떤 변수를 통해서 속성을 바꾸더라도 항상 같은 대상을 바꾸게 된다.
  • 어떤 것을 선택해야할까?
    • 값 형식의 메모리 처리방식, 참조 형식의 메모리 처리방식
    • 두 형식의 차이점을 알고 구현목적에 맞게 선택 - 하지만 경험이 필요
    • 일반적인 구현 지침
      • OOP에서는 대부분 참조형식인 class로 구현
      • 상대적으로 적은 데이터를 저장하고 상속이 필요하지 않다면 값형식으로 구현
      • 값이 전달되는 시점마다 복사본이 생성되어야 한다면 값형식으로 구현
      • 연관된 상수 그룹을 표현할때는 열거형
      • 코드내에서 한번만 사용되는 형식은 튜플
      • 나머지 값형식은 모두 구조체




Nested Types

Nested Types는 한국어로 포함된 형식, 내포된 형식으로 번역된다. 단순하게 정의하면 형식 내부에 선언된 형식이다.

Nested Types 선언

String.CompareOptions

String -> Structure
CompareOptions -> Structure
// 특별한 선언 문법이 필요없이 단순히 다른 형식 내부에 선언하면 내포된 형식이 된다.
class One {
    struct Two {
        enum Three {
            case a

            class Four {

            }
        }
    }

    var a = Two() // One 생략가능
}

let two: One.Two = One.Two()

Nested Types 장점

  • 가독성

NumberFormatter, DateFormatter??

'Swift' 카테고리의 다른 글

[Swift] Property  (0) 2021.03.11
[Swift] Collection - Array, Dictionary, Set  (0) 2021.03.09
[Swift] Closure  (0) 2021.03.08
[Swift] Enumerations (열거형)  (0) 2021.03.03
[Swift] Functions (함수)  (0) 2021.02.20
댓글