클래스
클래스는 참조타입(RefrenceType)이다.
힙의 영역에 실제 데이터를 저장하고 스택영역에선 힙영역의 주소를 가리킨다.
그래서 주소를 참조하는 참조타입이다.
복사시 값을 복사하는게 아니라 주소를 전달해서 동일한 데이터를 가리키게 만든다. (메모리 변경 X)
그러므로 복사된 객체의 값을 바꾸면 원본값도 함께 바뀐다.
힙(Heap)의 공간에 저장하므로, ARC시스템을 통해 메모리를 관리한다.
class Person{
var name = "사람"
}
var p = Person() //p에 담긴값 주소: x123124
var p2 = p //p2에 담긴값 주소: x123124
//p와 p2는 클래스이므로 같은 주소값을 갖는다.
p.name //사람
p2.name = "미진" //미진
p.name //미진
//p와 p2는 같은 주소공간을 가리키므로
//p가 변경되면 p2도 변경된다.
//p2가 변경되면 p도 변경된다.
구조체
구조체는 값타입(ValueType)이다.
스택영역에 실제 데이터를 저장한다.
그래서 값을 참조하는 값타입(ValueType)이다.
복사시 값을 복사하므로 서로 다른 데이터가 된다. (다른 메모리 공간 차지)
복사본을 변경하더라도 원본은 바뀌지 않는다.
스택(Stack)영역에 저장하므로 스택프레임이 끝나면 메모리에서 자동제거된다.
struct Animal{
var name = "동물"
}
var a = Animal() //a에 담긴 값: name = 동물
var b = a //b에 담긴 값: name = 동물
b.name = "강아지"
b.name //강아지
a.name //동물
//값을 복사하므로 새로운 메모리 영역에 a와 같은 구조체가 생성된다.
//그럼 서로 다른 메모리상에 존재하므로 서로 다른 Animal구조체이다.
클래스와 구조체의 let과 var키워드
class PersonClass{
var name = "인간"
var age = 0
}
struct AnimalStruct{
var name = "덩물"
var age = 0
}
//클래스(class)
let pclass = PersonClass() //상수선언, name = "인간"
pclass.name = "사람1"
pclass.name //사람1
//상수선언을 했지만 name을 변경할 수 있다.
//pclass에 저장된 값은 pclass의 참조주소값이다.(값이 아님)
//주소값을 타고 들어간 힙 영역에서 name은 var로 선언되어있다. 그러므로 변경 가능
//상수선언으로 인해 바꾸지 못하는 것은 value가 아닌 참조주소값이다.(다른 객체를 참조하지 못함)
//구조체(struct)
let astruct = AnimalStruct() //상수선언, name = "덩물"
pclass.name = "사람1" //에러발생 상수이므로 변경할 수 없다.
pclass.name //덩물
//구조체는 메모리주소가 아닌 값을 지닌다.
//그러므로 값을 바꿀 수 없다.
구조체와 클래스의 차이
구조체(struct) | 클래스(class) | |
타입 | Value Type(값 형식) | Refernce Type(참조 형식) |
메모리 관련 | 값의 저장: Stack / 복사 전달 | 값의 저장: Heap / 주소전달 |
let/ var | 인스턴스 상수(let)로 선언 시 저장속성이 전부 상수로 선언됨 |
let으로 선언하면 가르키는 인스턴스 고정 (저장속성은 각 let/var선언에 따름 |
생성자 관련 | 멤버 이니셜라이저 (자동)제공 | 편의 생성자 존재 |
메서드 + 속성 | 메서드 내 속성 변경 원칙적으로 불가능 mutating키워드로 가능 |
메서드 내 속성 변경 가능 |
소멸자 | 없음 | 있음 |
상속 가능 | 불가능 | 가능(클래스가 유일) |
값형식(구조체)
값형식: Value Type
값 저장: Stack, 값 복사 전달.
메모리 관리: 스택스코프가 종료되면 자동제거
Int, String, 튜플, 열거형, 컬렉션, 구조체
참조(클래스형식)
값형식: Refernce Type
값 저장: Heap, 주소전달, 주소를 Stack에 저장
메모리 관리: RC(Reference Counting)을 통해 메모리관리.. ARC모델
클래스, 클로저
구조체와 클래스의 사용차이
애플은 구조체 사용을 권장한다. 정답이 있는것은 아니다. 프로젝트의 사례 적합성에 따라 선택한다.
구조체가 클래스보다 가볍다. 많은 경우 구조체를 사용한다.
클래스는 조금 무겁다. 힙의 영역에 데이터를 보관하기 때문이다. 힙의 영역은 데이터를 조금 더 길게 보관하기 위해 사용한다.
구조체
연관 데이터들을 단순히 캡슐화하는 것이 목적일때 구조체 사용
구조체에 저장된 저장 속성들이 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때 구조체 사용
구조체에 저장된 속성들이 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때 구조체 사용
클래스
데이터에서 상속 구조가 필요하면 클래스 사용
해당 모델을 serialize해서 전송하거나 파일로 저장할 경우가 발생하면 클래스 사용
*필연적으로 클래스는 구조체보다 여러가지 면에서 속도가 느릴 수 밖에 없으므로 차이점을 명확하게 인지하고, 굳이 필요한 경우에만 클래스 사용
객체지향프로그래밍 (Objective-Oriented-Programming)
객체는 클래스에서 하나 하나 찍어낸 붕어빵?들을 객체라고함..
1) 추상화(Abstraction) 모델링
- 구체적인것을 관찰자가 관심있는 부분만 가지고 재조합하는 것
- 공통적인 특성을 뽑아내서 하나의 분류(class)로 만듬
- 객체지향의 관점에서, 실체들의 공통적 특성을 선택해서 클래스로 정의하는 것 자체가 추상화의 개념
예) 영화관리프로그램 -> 제목, 작가, 감독, 출연진, 배급사
2) 캡슐화(Encapsulation) 모델링 / 정보 은닉 / 데이터 캡슐화
- 연관있는 속성과 메서드를 "하나의 클래스로 묶어서 활용하는개념"
예) 영화관리프로그램의 속성들을 하나의 클래스로 묶음
*추상화는 디자인레벨의 관점, 캡슐화는 실제코드구현레벨의 관점
- 은닉화: 캡슐화를 해서 접근제어자(private, public등)를 사용해 객체 외부에서 내부데이터 접근의 통제가 가능해짐
3) 상속성(Inheritance) 재사용 / 확장
- 부모클래스의 속성과 메서드를 자식클래스에서 그대로 물려받는 개념
- 상속을 통해 코드가 재활용되기 때문에 생산성이 높아짐
4) 다형성(Polymorphism) 사용편의 / 동적바인딩
- 하나의 객체가 여러가지 타입의 형태로 저장 될 수 있고, 다양한 메서드의 형태로 동작 가능함
(하나의 객체는 부모의 타입으로도 저장이 가능하고, 프로토콜 타입으로도 저장이 가능)
- 하나의 객체는 다양한 방식으로 동작가능(동적 바인딩/MethodDispatch)
(또한 오버라이딩(overriding)과 오버로딩(overloading)을 통해 하나의 메서드나 클래스를 다양한 방법으로 동작시키는 것을 포함하는 개념
캡상추다