You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
구조체(structure)와 클래스(class)는 보통 프로그램 코드 블록을 유연성 있게 구축하기 위해 사용되어 추상화
상수, 변수, 함수를 정의하는 것과 같은 문법을 사용해
구조체와 클래스에 프로퍼티(property)와 메소드(method)를 정의 가능
다른 언어와 달리 Swift는 구조체와 클래스로부터 인터페이스와 구현을 분리하지 않아도 된다
구조체 또는 클래스를 하나의 파일에 정의하면 Swift가 자동으로 해당 클래스와 구조체를 사용할 수 있는 인터페이스를 만들어 준다
클래스의 인터페이스는 전통적으로 객체로 알려져 있다
하지만 Swift 구조체와 클래스는 다른 언어보다 더 기능성(funtionality)에 가깝고
해당 챕터에선 클래스나 구조체 타입의 인스턴스에 적용되는 기능에 대해 설명
구조체와 클래스의 비교
구조체와 클래스의 공통점
값을 저장하기 위한 프로퍼티를 정의
기능성을 제공하기 위한 메소드를 정의
subscript 문법을 사용하는 값에 접근하기 위한 subscript 문법을 정의 - id
초기화 상태를 설정하기 위한 initializer를 정의
기본적인 구현을 넘어서 기능성을 확장
특정한 종류의 표준 기능성을 제공하기 위한 프로토콜을 준수
클래스에만 있는 추가적인 기능
상속 (inheritance) : 한 클래스가 다른 클래스를 상속 가능
타입 캐스팅 (type casting) : 런타임 시에 클래스 인스턴스의 타입을 확인하고 이해하기 위한 타입 캐스팅이 가능
소멸자 (deinitializer) : 할당된 자원을 해제 가능
참조 카운팅 (reference counting) : 클래스 인스턴스에 하나 이상의 참조를 가능 - ARC
클래스가 지원하는 추가적인 기능은 복잡성의 증가로 인한 비용 상승을 초래 - 메모리 사용 관련
가이드라인에 따르면, 사용하기 쉽기 때문에 구조체를 더 선호, 클래스는 적합하고 필요할 때만 사용
대부분의 커스텀 데이터 타입은 구조체 혹은 열거형으로 정의
Class와 Actor는 동일한 특성과 동작을 많이 공유 - 동시성 모델 참고
구조체와 클래스는 앱에서 데이터를 저장하고 동작을 모델링하는 데 좋은 선택이지만,
둘의 유사성으로 인해 서로를 선택하기 어려울 수 있다
기본적으로 구조체를 사용
구조체의 주 목적이 관계된 간단한 값을 캡슐화(encapsulate)를 위한 경우
인스턴스, 내부 프로퍼티가 참조되기 보다 복사되기를 기대하는 경우
구조체가 프로퍼티나 메소드 등을 상속할 필요가 없는 경우
Objective-C 상호 운용성이 필요할 때 클래스를 사용
모델링하는 데이터의 ID를 제어해야 하는 경우 클래스를 사용
프로토콜과 함께 구조체를 사용하여 구현을 공유하여 동작을 채택
1) 정의 문법
구조체와 클래스는 비슷한 정의 문법을 가짐
struct 또는 class 키워드로 구조체나 클래스를 선언
structSomeStructure{// structure definition goes here}classSomeClass{// class definition goes here}
구조체나 클래스를 정의할 때마다 새로운 Swift 타입이 정의
UpperCamelCase로 작성하는 것을 원칙
내부 프로퍼티나 메소드는 lowerCamelCase로 선언
// 화면의 해상도를 묘사하는 Resolution 구조체를 정의structResolution{// 프로퍼티 정의 - 저장되고 묶이는 상수 또는 변수varwidth=0varheight=0}// 비디오 화면의 특정 모드를 묘사하는 VideoMode 클래스 정릐classVideoMode{// 프로퍼티 정의 - 저장되고 묶이는 상수 또는 변수// resolution은 새로운 Resolution 구조체 인스턴스로 초기화varresolution=Resolution()varinterlaced= false
varframeRate= 0.0
varname:String?}
2) 구조체와 클래스 인스턴스
Resolution 구조체 정의와 VideoMode 클래스 정의는 해당 구조체 / 클래스가 어떻게 구성이 되었는지 나타낸다
자체는 특정한 해상도와 비디오 모드를 묘사하지 않는다
구체성을 위해 새로운 인스턴스를 초기화, 생성 문법은 구조체와 클래스가 유사
구조체와 클래스는 모두 새로운 인스턴스를 위한 initializer 문법을 사용
가장 간단한 형태는 구조체, 클래스의 타입 이름을 빈 소괄호와 함께 사용
새로운 인스턴스를 생성하며, 그 인스턴스의 모든 프로퍼티는 기본 값으로 초기화
3) 프로퍼티 엑세스
점 문법을 사용하여 인스턴스의 프로퍼티에 접근 가능
인스턴스 이름 뒤에 바로 점과 프로퍼티 이름을 표기
계층에 따른 접근과 변수 값의 할당 가능
print("The width of someResolution is \(someResolution.width)")// Prints "The width of someResolution is 0"// someResolution.width 는 someResolution의 width 프로퍼티로 추론되며, 기본 값인 0을 반환print("The width of someVideoMode is \(someVideoMode.resolution.width)")// Prints "The width of someVideoMode is 0"// VideoMode의 resolution 프로퍼티 안 width 프로퍼티와 같이 subproperty에 깊게 접근 가능
someVideoMode.resolution.width =1280print("The width of someVideoMode is now \(someVideoMode.resolution.width)")// Prints "The width of someVideoMode is now 1280"// 변수 프로퍼티에 새로운 값을 할당하기 위해 점 문법을 사용
4) 구조체 타입의 Memberwise Initailizers
모든 구조체는 자동적으로 memberwise initializer를 생성
새로운 구조체 인스턴스의 멤버 프로퍼티를 초기화 하는 데 사용 가능
새로운 인스턴스의 프로퍼티에 대한 초기 값은 이름에 의해 memberwise initializer에 전달 가능
letvga=Resolution(width:640, height:480)// 구조체와 다르게 클래스 인스턴스는 기본 Memberwise Initailizers를 받지 않음
값 타입으로 구조체와 열거형
값 타입(value type)은 상수/변수에 할당되거나 함수에 들어갈 때 그 값이 복사되어 전달된다는 의미를 지닌다
Swift에서 모든 기본 타입(정수, 실수, Boolean, 문자열, 배열, 딕셔너리)은 값 타입이고, 기본적으로 구조체로써 구현
커스텀하게 만든 모든 구조체와 열거형 역시 값 타입
새롭게 생성하는 모든 구조체와 열거형은(그것들의 프로퍼티를 포함하여) 항상 복사되어 코드에 전달된다
배열, 딕셔너리, 문자열같은 기본 라이브러리에 의해 정의된 컬렉션 타입은 복사의 퍼포먼스 비용을 줄이기 위한 최적화를 실시
즉시 복사본을 생성하는 게 아니라 원본과 복사본이 메모리 공간을 공유하다가
만약 컬렉션의 복사본 중 하나가 수정될 경우, 수정 직전에 해당 원소는 복사
lethd=Resolution(width:1920, height:1080)varcinema= hd
cinema.width =2048print("cinema is now \(cinema.width) pixels wide")// Prints "cinema is now 2048 pixels wide"print("hd is still \(hd.width) pixels wide")// Prints "hd is still 1920 pixels wide"
Resolution은 구조체이기 때문에, 기존 인스턴스의 복사본이 생성
복사본이 cinema에 할당
hd와 cinema가 같은 너비와 높이를 갖고 있을지라도 둘은 완벽히 다른 인스턴스
cinema의 width 프로퍼티를 2048로 늘린 결과
분리된 인스턴스기 때문에, cinema의 width를 수정해도 hd의 width는 영향을 받지 않음
열거형에도 같은 원리가 적용
enumCompassPoint{case north, south, east, west
mutatingfunc turnNorth(){self=.north
}}varcurrentDirection=CompassPoint.west
letrememberedDirection= currentDirection
currentDirection.turnNorth()print("The current direction is \(currentDirection)")print("The remembered direction is \(rememberedDirection)")// Prints "The current direction is north"// Prints "The remembered direction is west"
currentDirection의 값을 turnNorth() 메서드를 이용해 수정해도 rememberedDirection은 영향을 받지 않음
참조 타입으로 클래스
값 타입과 달리, 참조 타입은 변수나 상수에 할당되거나 함수에 전달될 때 복사되지 않는다
참조는 기존의 동일한 인스턴스를 활용
lettenEighty=VideoMode()
tenEighty.resolution =Resolution(width:1920, height:1080)
tenEighty.interlaced = true
tenEighty.name ="1080i"
tenEighty.frameRate = 25.0
letalsoTenEighty= tenEighty
alsoTenEighty.frameRate = 30.0
print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")// Prints "The frameRate property of tenEighty is now 30.0"
클래스는 참조 타입이기 때문에, tenEighty와 alsoTenEighty는 같은 VideoMode 인스턴스를 참조
하나의 같은 인스턴스를 위한 두 가지의 이름이 있는 것
tenEighty의 frameRate 프로퍼티를 확인하면 30.0으로 변한 것을 확인 가능
예시는 참조 타입이 추론하기 어렵다는 것을 보여준다
tenEighty와 alsoTenEighty가 지금 작성하는 코드에서 멀리 떨어져 있다면,
바뀐 VideoMode를 모두 확인하는 것은 매우 어려운 일
tenEighty을 사용 중이더라도 alsoTenEighty을 사용하는 코드를 고려해야하며 반대의 경우도 마찬가지
tenEighty와 alsoTenEighty를 상수로 선언했음에도
tenEighty.frameRate와 alsoTenEighty.frameRate를 통해 프로퍼티를 변경할 수 있었다
tenEighty와 alsoTenEighty 상수 그 자체의 값은 사실상 바뀌지 않기 때문
tenEighty와 alsoTenEighty는 VideoMode 인스턴스를 저장하지 않는다
VideoMode 인스턴스의 메모리를 참조한다
VideoMode의 상수 레퍼런스 값이 아니라 내부 frameRate 프로퍼티가 변하는 것
1) 식별 연산자
클래스는 참조 타입이어서 하나의 동일한 클래스 인스턴스를 여러 상수 / 변수가 참조하는 것이 가능
구조체나 열거형은 항상 복사본을 저장하기 때문에 이와 다르다
두 상수 / 변수가 정확히 같은 클래스의 인스턴스를 참조하고 있는지를 확인하기 위해 두 식별 연산자를 사용한다
=== : 동일할 경우(identical) 참.
!== : 동일하지 않을 경우(not identical) 참.
if tenEighty === alsoTenEighty {print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")}// Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance."
identical to(===)와 equal to(==)가 같은 의미가 아니라는 것에 주목해보자
identical to(===)는 클래스 타입의 두 상수/변수가 정확히 같은 클래스 인스턴스 참조하는지 확인 - 메모리 주소
equal to(==)는 두 인스턴스가 값이 상등(equel, 같다/틀리다)하거나 동등(equivalent, 크다/작다/같다)한지를 고려
2) 포인터 (Pointers)
C, C++, Objective-C는 메모리의 주소를 참조하기 위한 포인터(pointer)를 사용
몇 몇 참조 타입의 인스턴스를 참조하는 Swift의 상수와 변수는 C의 포인터와 비슷
하지만, 메모리 주소에 대한 직접적인 포인터는 아니다
새로운 레퍼런스를 생성한다는 것을 표시하기 위해 별표(*)를 작성할 필요도 없다
대신 이러한 레퍼런스는 Swift의 다른 상수/변수와 같이 정의
표준 라이브러리는 직접적으로 포인터와 상호작용하고자 할 경우 포인터와 버퍼 타입을 제공 - 수동적 메모리 관리 가능
The text was updated successfully, but these errors were encountered:
구조체(structure)와 클래스(class)는 보통 프로그램 코드 블록을 유연성 있게 구축하기 위해 사용되어 추상화
상수, 변수, 함수를 정의하는 것과 같은 문법을 사용해
구조체와 클래스에 프로퍼티(property)와 메소드(method)를 정의 가능
다른 언어와 달리 Swift는 구조체와 클래스로부터 인터페이스와 구현을 분리하지 않아도 된다
구조체 또는 클래스를 하나의 파일에 정의하면 Swift가 자동으로 해당 클래스와 구조체를 사용할 수 있는 인터페이스를 만들어 준다
클래스의 인터페이스는 전통적으로 객체로 알려져 있다
하지만 Swift 구조체와 클래스는 다른 언어보다 더 기능성(funtionality)에 가깝고
해당 챕터에선 클래스나 구조체 타입의 인스턴스에 적용되는 기능에 대해 설명
구조체와 클래스의 비교
구조체와 클래스의 공통점
클래스에만 있는 추가적인 기능
구조체와 클래스는 앱에서 데이터를 저장하고 동작을 모델링하는 데 좋은 선택이지만,
둘의 유사성으로 인해 서로를 선택하기 어려울 수 있다
1) 정의 문법
구조체와 클래스는 비슷한 정의 문법을 가짐
struct 또는 class 키워드로 구조체나 클래스를 선언
구조체나 클래스를 정의할 때마다 새로운 Swift 타입이 정의
UpperCamelCase로 작성하는 것을 원칙
내부 프로퍼티나 메소드는 lowerCamelCase로 선언
2) 구조체와 클래스 인스턴스
Resolution 구조체 정의와 VideoMode 클래스 정의는 해당 구조체 / 클래스가 어떻게 구성이 되었는지 나타낸다
자체는 특정한 해상도와 비디오 모드를 묘사하지 않는다
구체성을 위해 새로운 인스턴스를 초기화, 생성 문법은 구조체와 클래스가 유사
구조체와 클래스는 모두 새로운 인스턴스를 위한 initializer 문법을 사용
가장 간단한 형태는 구조체, 클래스의 타입 이름을 빈 소괄호와 함께 사용
새로운 인스턴스를 생성하며, 그 인스턴스의 모든 프로퍼티는 기본 값으로 초기화
3) 프로퍼티 엑세스
점 문법을 사용하여 인스턴스의 프로퍼티에 접근 가능
인스턴스 이름 뒤에 바로 점과 프로퍼티 이름을 표기
계층에 따른 접근과 변수 값의 할당 가능
4) 구조체 타입의 Memberwise Initailizers
모든 구조체는 자동적으로 memberwise initializer를 생성
새로운 구조체 인스턴스의 멤버 프로퍼티를 초기화 하는 데 사용 가능
새로운 인스턴스의 프로퍼티에 대한 초기 값은 이름에 의해 memberwise initializer에 전달 가능
값 타입으로 구조체와 열거형
값 타입(value type)은 상수/변수에 할당되거나 함수에 들어갈 때 그 값이 복사되어 전달된다는 의미를 지닌다
Swift에서 모든 기본 타입(정수, 실수, Boolean, 문자열, 배열, 딕셔너리)은 값 타입이고, 기본적으로 구조체로써 구현
커스텀하게 만든 모든 구조체와 열거형 역시 값 타입
새롭게 생성하는 모든 구조체와 열거형은(그것들의 프로퍼티를 포함하여) 항상 복사되어 코드에 전달된다
Resolution은 구조체이기 때문에, 기존 인스턴스의 복사본이 생성
복사본이 cinema에 할당
hd와 cinema가 같은 너비와 높이를 갖고 있을지라도 둘은 완벽히 다른 인스턴스
cinema의 width 프로퍼티를 2048로 늘린 결과
분리된 인스턴스기 때문에, cinema의 width를 수정해도 hd의 width는 영향을 받지 않음
열거형에도 같은 원리가 적용
currentDirection의 값을 turnNorth() 메서드를 이용해 수정해도 rememberedDirection은 영향을 받지 않음
참조 타입으로 클래스
값 타입과 달리, 참조 타입은 변수나 상수에 할당되거나 함수에 전달될 때 복사되지 않는다
참조는 기존의 동일한 인스턴스를 활용
클래스는 참조 타입이기 때문에, tenEighty와 alsoTenEighty는 같은 VideoMode 인스턴스를 참조
하나의 같은 인스턴스를 위한 두 가지의 이름이 있는 것
tenEighty의 frameRate 프로퍼티를 확인하면 30.0으로 변한 것을 확인 가능
예시는 참조 타입이 추론하기 어렵다는 것을 보여준다
tenEighty와 alsoTenEighty가 지금 작성하는 코드에서 멀리 떨어져 있다면,
바뀐 VideoMode를 모두 확인하는 것은 매우 어려운 일
tenEighty을 사용 중이더라도 alsoTenEighty을 사용하는 코드를 고려해야하며 반대의 경우도 마찬가지
tenEighty와 alsoTenEighty를 상수로 선언했음에도
tenEighty.frameRate와 alsoTenEighty.frameRate를 통해 프로퍼티를 변경할 수 있었다
tenEighty와 alsoTenEighty 상수 그 자체의 값은 사실상 바뀌지 않기 때문
tenEighty와 alsoTenEighty는 VideoMode 인스턴스를 저장하지 않는다
VideoMode 인스턴스의 메모리를 참조한다
VideoMode의 상수 레퍼런스 값이 아니라 내부 frameRate 프로퍼티가 변하는 것
1) 식별 연산자
클래스는 참조 타입이어서 하나의 동일한 클래스 인스턴스를 여러 상수 / 변수가 참조하는 것이 가능
구조체나 열거형은 항상 복사본을 저장하기 때문에 이와 다르다
두 상수 / 변수가 정확히 같은 클래스의 인스턴스를 참조하고 있는지를 확인하기 위해 두 식별 연산자를 사용한다
identical to(===)와 equal to(==)가 같은 의미가 아니라는 것에 주목해보자
identical to(===)는 클래스 타입의 두 상수/변수가 정확히 같은 클래스 인스턴스 참조하는지 확인 - 메모리 주소
equal to(==)는 두 인스턴스가 값이 상등(equel, 같다/틀리다)하거나 동등(equivalent, 크다/작다/같다)한지를 고려
2) 포인터 (Pointers)
C, C++, Objective-C는 메모리의 주소를 참조하기 위한 포인터(pointer)를 사용
몇 몇 참조 타입의 인스턴스를 참조하는 Swift의 상수와 변수는 C의 포인터와 비슷
하지만, 메모리 주소에 대한 직접적인 포인터는 아니다
새로운 레퍼런스를 생성한다는 것을 표시하기 위해 별표(*)를 작성할 필요도 없다
대신 이러한 레퍼런스는 Swift의 다른 상수/변수와 같이 정의
표준 라이브러리는 직접적으로 포인터와 상호작용하고자 할 경우 포인터와 버퍼 타입을 제공 - 수동적 메모리 관리 가능
The text was updated successfully, but these errors were encountered: