ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 클래스와 구조체 (Classes and Structures)
    Swift 2020. 11. 10. 20:02

    클래스와 구조체는 코드를 좀 더 조직화시키기 위해서 사용합니다.

    Swift는 다른 프로그래밍 언어와 다르게 interface파일과 imlementation파일을 분리해서 만들지 않아도 됩니다.

    하나의 파일에 구조체나 클래스를 정의하면, Swif가 알아서 해당 클래스와 구조체를 사용할 수 있는 인터페이스를 생성해줍니다.

     

    클래스와 구조체의 비교 (Comparing Classes and Structures)

    공통점

    - 값을 저장하기 위한 프로퍼티 정의

    - 기능을 제공하기 위한 메서드 정의

    - subscript 문법을 이용해 특정 값을 접근할 수 있음

    - 초기 상태를 설정할 수 있는 initializer 정의

    - 기능 확장

    - 어떤 protocol을 따른다고 선언을 하였다면, protocol이 정한 규칙을 무조건 따라야 함. (conform to protocol)

     

    클래스만 가능한 기능

    - 상속 (Inheritance) : 클래스의 여러 속성을 다른 클래스에 물려줌

    - 타입 캐스팅 (Type Casting) : 런타임에 타입 체크

    - 소멸자 (Deinitializers) : 자원 해제

    - 참조 카운트 (Reference counting) : 클래스 인스턴스에 하나 이상의 참조가 가능

     

     

    선언 (Definition)

    class NumberClass {
    
    }
    
    struct NumberStruct {
    
    }

    -> 클래스나 구조체를 선언하는 것은 열거형과 같이 새로운 타입을 선언하는 것입니다.

     

    클래스와 구조체 인스턴스 (Class and Structures Instance)

    let numberClass = NumberClass()
    let numberStructure = NumberStruct()

    -> 인스턴스를 생성하는 방법입니다.

     

    프로퍼티 접근 (Accessing Properties)

    점(dot)문법을 이용하여 클래스 또는 구조체 프로퍼티, 하위 레벨 프로퍼티에 접근할 수 있으며, 값을 할당하는 것 또한 가능합니다.

     

     

    구조체 형의 멤버 초기화 (Memberwise Initializers for Structure Types)

    모든 구조체는 초기화를 할 때, 프로퍼티를 선언할 수 있는 Initializers를 자동으로 생성해줍니다. 

    let number = Number(one: 1, two: 2, three: 3)

     

     

    구조체와 열거형은 값 타입 (Structures and Enumerations Are Value Types)

    값 타입의 의미는 함수에서 상수나 변수에 값이 전달될 때, 해당 값이 복사돼서 전달된다는 의미입니다. 

    let number = Number(one: 1, two: 2, three: 3)
    var num = number

    -> 위의 예제에서 num과 number는 같은 인스턴스가 아닙니다. 값이 전달될 때, 복사돼서 전달되었다고 했으니, num은 복사된 새로운 인스턴스입니다. 따라서 num.one = 4로 새롭게 값을 할당하여도 number.one은 여전히 1입니다.

    -> 열거형도 구조체와 마찬가지로 값이 복사돼서 전달되기 때문에 같은 인스턴스라고 할 수 없습니다.

     

     

    클래스는 참조 타입 (Classes Are Reference Types)

    참조 타입은 변수나 상수에 값을 할당하거나 함수에 인자로 전달될 때, 복사되는 것이 아니라 참조가 됩니다.

    여기서 참조란, 변수나 상수에 값이 할당이 되면 메모리의 어떤 곳에 할당이 되는데, 참조를 하게 되면 해당 메모리를 참조하겠다는 의미입니다.

    따라서 위의 예제를 이용해보면

    Number라는 class가 존재했을 때,

    let number = Number()
    number.one = 1
    number.two = 2
    number.three = 3
    
    let anotherNumber = number
    anotherNumber.one = 4

    -> 이 코드는 위에서 예시로 들었던 struct와 유사합니다. 하지만 이 코드에서 만약 number.one을 print 해보면, 4가 출력되는 것을 볼 수 있습니다. 그 이유는 anotherNumber = number의 의미는 number가 참조하는 메모리를 anotherNumber 또한 참조하겠다는 의미이기 때문입니다.

    -> 그리고 anotherNumber를 let으로 선언했지만 값을 바꿀 수 있는 이유는 상수로 설정한 anotherNumber자체를 변경하는 것이 아닌 그것이 바라보고 있는 값을 변경한 것이므로 가능합니다.

    (구조체의 경우에는 인스턴스가 복사되는 것이어서, 만약 값을 변경한다면, 인스턴스의 값을 직접 변경하는 것이기 때문에 에러가 발생하지만 클래스의 경우에는 인스턴스가 참조하는 곳의 값을 변경하는 것이기 때문에 에러가 발생하지 않습니다.)

     

     

    식별 연산자 (Identity Operators)

    클래스는 참조 타입이기 때문에 상수와 변수가 같은 인스턴스를 참조하고 있는지 비교할 수도 있습니다.

    - === : 두 상수나 변수가 같은 인스턴스를 참조하고 있는 경우 참

    - !== : 두 상수나 변수가 다른 인스턴스를 참조하고 있는 경우 참

     

     

     

    클래스와 구조체의 선택 (Choosing Between Classes and Structures)

    클래스와 구조체 둘 중 무엇을 선택해야 할지 고민일 때 아래의 사항중 1개 이상을 만족하면 구조체를 사용하는 것을 고려할 수 있습니다.

    - 구조체의 주목적이 관계가 있는 값들을 캡슐화(encapsulate) 하기 위한 경우

    - 구조체의 인스턴스가 참조보다는 복사되기를 원하는 경우

    - 구조체에 의해 저장된 프로퍼티가 참조되기보다는 복사되기를 원하는 경우

    - 구조체가 프로퍼티나 메서드 등을 상속할 필요가 없는 경우

    ( 예를 들어서 Double형을 갖는 width와 height을 캡슐화해서 크기를 나타내기 위해 사용하는 경우, Int형을 갖는 start와 length를 캡슐화해서 특정 값의 범위를 나타내는 경우, Double형으로 구성된 x, y, z를 캡슐화해서 3차원의 point로 사용하는 경우 )

     

    String, Array, Dictionary의 할당과 복사 동작 (Assignment and Copy Behavior for Strings, Arrays, and Dictionaries)

    Swift에서는 String, Array, Dictionary 같은 데이터 타입이 구조체로 구현되어 있습니다. 

    반면, Foundation의 NSString, NSArray, NSDictionary는 클래스로 구현되어있습니다.

    -> 하지만 실제로는 String, Array, Dictionary는 할당하거나 전달될 때, 최적의 성능을 위해 필요한 경우에만 복사됩니다.

     

    'Swift' 카테고리의 다른 글

    상속 (Inheritance)  (0) 2020.12.10
    메소드 (Methods)  (0) 2020.12.08
    클로저 (Closures)  (0) 2020.12.05
    프로퍼티 (Properties)  (0) 2020.11.10
    열거형 (Enumerations)  (0) 2020.11.05

    댓글

Designed by Tistory.