Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Swift] Struct와 Class #46

Closed
Suyeon9911 opened this issue May 23, 2022 · 1 comment
Closed

[Swift] Struct와 Class #46

Suyeon9911 opened this issue May 23, 2022 · 1 comment
Assignees
Labels

Comments

@Suyeon9911
Copy link
Owner

구조체와 클래스

구조체의 인스턴스는 값 타입
클래스의 인스턴스는 참조 타입

구조체

struct 키워드, 구조체 정의를 마친 후 인스턴스를 생성하고 초기화하고자 할때는 기본적으로 생성되는
멤버와이즈 이니셜라이저 사용 , 구조체에 기본 생성된 이니셜라이저의 매개변수는 구조체의 프로퍼티 이름으로 자동 지정
=> 프로퍼티 이름으로 자동 생성된 이니셜라이저를 사용하여 구조체 생성 가능
구조체를 var로 선언하게 될 경우 .으로 접근하여 값 변경 가능

  • 사용자 정의 이니셜라이저도 구현 가능

클래스

class 키워드, 부모클래스 없어도 상속없이 단독으로 정의 가능
클래스를 정의한 후 , 인스턴스를 생성하고 초기화 하고자 할때는 기본적인 이니셜라이저를 사용합니다.
인스턴스가 생성되고 초기화된 후 프로퍼티 값에 접근하려면 마침표 사ㅛㅇㅇ.
구조체와 다른게 클래스의 인스턴스는 참조 타입이므로 클래스의 인스턴스를 let으로 선언해도 내부 프로퍼티 값을 변경할 수 있다.

클래스 인스턴스의 소멸

클래스의 인스턴스는 참조타입이므로 더는 참조할 필요가 없을 때 메모리에서 해제 됩니다.
이 과정을 소멸이라고 하는데, 소멸되기 직전 deinit이라는 메서드 호출
클래스 내부에 deinit 메서드를 구현해주면, 소멸되기 직전에 호출됨
클래스당 하나만 구현, 매개변수와 반환값을 가질 수 없음

구조체와 클래스의 차이 !

공통점

  • 값을 저장하기 위해 프로퍼티를 정의할 수 있습니다.
  • 기능 실행을 위해 메서드를 정의할 수 있습니다.
  • 서브스크립트 문법을 통해 구조체 또는 클래스가 갖는 값에 접근 하도록 서브스크립트르 정의할 수 있음
  • 초기화 될때의 상태를 지정하기 위해 이니셜라이저를 정의할 수 있습니다.
  • 초기구현과 더불어 새로운 기능 추가를 위해 익스텐션을 통해 확장할 수 있습니다.
  • 특정 기능을 실행하기 위해 특정 프로토콜을 준수할 수 있습니다.

차이점

  • 구조체는 상속할 수 없습니다.
  • 타입캐스팅은 클래스의 인스턴스에만 허용됩니다.
  • 디이니셜라이저는 클래스의 인스턴스에만 활용할 수 있습니다.
  • 참조횟수 계산은 클래스의 인스턴스에만 적용됩니다.

값 타입과 참조 타입 ??

  • 무엇이 전달되느냐??
    어던 함수의 전달 인자로 값 타입의 값을 넘긴다면 전달될 값이 복사되어 전달됩니다.
    그러나 참조 타입이 전달인자로 전달될때는 값을 복사하지 않고 참조(주소)가 전달됩니다.
    함수의 전달인자로 넘길때도 참조가 전달되며 다른 변수 또는 상수에 할당될 때도 마찬가지로 참조가 할당된다 !

값 타입

struct BasicInformation{
	let name: String
	var age: Int
}

var yagomInfo: BasicInformation = BasicInformation(name: "yagom", age: 99)
yagomInfo.age = 100

//friendInfo 에 yagomInfo 의 값을 "복사"하여 할당 (extra memory)
var friendInfo: BasicInformation = yagomInfo

print("yagom's age: \(yagomInfo.age)")
print("friend's age: \(friendInfo.age)")

friendInfo.age = 25
//friendInfo 는 별도의 메모리를 할당 받았기 때문에 yagomInfo.age 에는 값 변경 X

func changeBasicInfo(_ info: BasicInformation){
	var copiedInfo: BasicInformation = info
	copiedInfo.age = 1
}

changeBasicInfo(yagomInfo)
print("yagom's age: \(yagomInfo.age)")
//call by reference 가 아닌 call by value 이기 때문에 따로 값이 변경되지 않고 그대로 100임

참조타입

class Person{
	var height: Float = 0.0
	var weight: Float = 0.0
}

var yagom: Person = Person()
var friend: Person = yagom
//yagom의 참조를 할당한다

friend.height = 182.3
print("yagom height: \(yagom.height)")
//friend.height 을 바꿨음에도 불구하고 yagom.height 도 같이 변경된다
//같은 메모리를 참조하기 때문

func changePersonInfo(_ info: Person){
	info.height = 155.2
}

changePersonInfo(yagom)
print("yagom height: \(yagom.height)")
//Call by reference 이기 때문에 실제 값이 변화되어 155.2 출력
  • 식별연산자 === : 클래스의 인스턴스끼리 참조가 같은지 확인할 때 사용 !
@Suyeon9911 Suyeon9911 self-assigned this May 23, 2022
@Suyeon9911
Copy link
Owner Author

스위프트의 기본 데이터 타입은 모두 구조체

애플의 가이드라인에서 다음 조건 중 하나 이상에 해당한다면 구조체를 사용하는 것을 권장

  • 연관된 간단한 값의 집합을 캡슐화하는 것만이 목적일 떄
  • 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
  • 구조체에 저장된 프로퍼티가 값타입이며, 참조하는 것 보다 복사하는 것이 합당할 때
  • 다른 타입으로 부터 상속 받거나 자신을 상속할 필요가 없을 때

적절한 예로는 좌표계가 있습니다.

  • 좌표를 표현하고 싶을때 Int 타입으로 x,y 프로퍼티 생성
  • 대다수 사용자 정의 데이터 타입은 클래스로 구현할일이 더 많을 것

스위프트의 복사 처리

스위프트의 기본 데이터 타입이 모두 구조체라서 다수의 배열 또는 딕셔너리 등의 데이터를 복사하고 ㄱ이용할 때 메모리를 비효율적으로 사용한다고 오해할 수 있음. 하지만, 스위프트는 꼭 필요한 경우에만 진짜복사를 한다
컴파일러가 판단해서 알아서 효율적으로 처리

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant