iJoom
Denovation Dev information
iJoom
전체 방문자
오늘
어제
  • 분류 전체보기 (29)
    • Swift information (5)
    • Deep Dive iOS (10)
    • Books (1)
    • Conference (1)
    • 알고리즘 풀이 (10)
    • 알고리즘 개념 및 Tool C++ (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • MergeConflicts
  • 자료형에러
  • C++
  • 완전탐색
  • 순열
  • sceneWillResignActive
  • 문자열
  • 문자열압축
  • applicationWillResignActive
  • decdoingError
  • struct
  • Swift Concurrency
  • Core OS
  • unowned
  • 알고리즘
  • ios
  • SWIFT
  • permuation
  • EscapingClosure
  • ARC
  • sidetable
  • Weak
  • 백준
  • iOS Structure
  • bj4344
  • Cocoa Touch
  • ValuesCapturing
  • 캡처리스트
  • Strong
  • Core Services

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
iJoom

Denovation Dev information

Swift information

Struct와 Class에서의 let 과 var의 차이에 대하여

2021. 11. 2. 15:04

값(Value)형태와 레펀러스(Reference) 참조 형태의 차이를 가진 Struct와 Class에서의 let 선언과 var 선언의 차이의 핵심을 알아보겠습니다 ~

 


class T1 {
	var name: String?
	init(_ name: String?){
		self.name = name	
	}
}

var a = T1("1") //T1("1") 주소 100이라고 가정
a = T1("2") //T1("2") 주소 102이라고 가정
//새로운 인스턴스 주소를 가리킬 수 있음

let b = T1("immutable")
//새로운 인스턴스 주소를 가리킬 수 없음
//b.name = "변경가능"
//heap 인스턴스에서 변수를 가진 name 영역은 변경가능
let c = b
let d = b
b = T1("변경")
//에러발생

print(d.name)
//immutable 출력

먼저 위의 코드에서 a,b,c,d 를 ViewController 안에 있는 지역변수라고 가정하겠습니다.

 

그렇다면 지역 변수 a는 heap 영역의 T1 Instance (주소 100이라고 가정) 를 가리키고 있습니다. 또한 a 인스턴스는 var 형태로 선언되었기 때문에 , 새로운 T1 클래스 인스턴스의 주소(102) 를 가리킬 수 있습니다.

 

Class에서는 스택영역에서 heap 인스턴스를 가리키는 주소를 변경할 수 있느냐 없느냐의 차이를 가집니다.

 

let으로 선언된 b 는 새로운 인스턴스의 주소를 가리킬 수 없습니다. 즉, heap 영역을 가리키는 주소변경이 불가능합니다. 하지만 heap 영역내의 변수인 name의 변경은 가능합니다.

 

그렇다면 다음과 같은 상황은 어떨까요?

 

class T1 {
	var name: String?
	init(_ name: String?){
		self.name = name	
	}
}

var a = T1("1")
a = T1("2")


var b = T1("immutable")
let c = b
let d = b

b = T1("test instance")
print(b.name) //test instance 출력
print(d.name) //immutable
print(c.name) //immutable

b를 참조하는 c,d 는 let으로 상수로 선언되어있습니다. 하지만 T1인스턴스를 가리키는 b는 var 로 선언되었습니다. 즉, 새로운 인스턴스 주소를 가리킬 수 있습니다.

 

이 형태에서는 c와 d는 기존의 immutable 인스턴스를 가리키고 있으며, var b는 새로운 주소를 가진 T1("test instance")를 가리키게 됩니다.

 


자, 이제 구조체 Value 형태로 넘어가 봅시다 ~

struct Value {
    var value = 0
    var name: String?

	init(name: String?) {
		self.name = name
	}
	
	func printValue() {
        print(value)
    }
	
    mutating func changeValue(v: Int) {
        value = v
    }
}

let a = Value(name: "Damwon")
a.name = "변경할래용" // 에러
a.changeValue(v: 400) // mutating keyword가 붙어있어도 에러

a = Value(name: "T1")
//Stack 영역에서의 새로운 주소 변경이 불가능하다.

새로운 인스턴스의 변경은 Class와 동일해 보인다. 하지만 내부 데이터 변경은 완전히 다르다.

Class에서는 let으로 선언된 인스턴스의 변수의 수정이 가능했지만, Struct는 stack에 저장되는 값 데이터 이므로 구조체 안의 변수가 var 이여도 값 변경이 불가능하다.

 

var a = Value(name: "Damwon")

a.name = "변경할래용" 
a.changeValue(v: 400)

//var a 선언이므로, 모두 값 변경 가능

 

반면, 위와 같이 var 선언시 값 변경과 mutating func을 이용해 내부 값을 변경할 수 있다.

 

var a = Value(name: "Damwon")
let b = a
let c = a

a = Value(name: "T1")

print(a)
print(b)
print(c)

//출력결과:
// Value(value: 0, name: Optional("T1"))
// Value(value: 0, name: Optional("Damwon"))
// Value(value: 0, name: Optional("Damwon"))

 

생성된 인스턴스 주소의 변경 가능성, 생성된 인스턴스의 내부 값 변경이 필요한지 안 필요한지 그리고 값 과 레퍼런스타입을 잘 구별하여 프로젝트에 적응해야 합니다 !.!

 

 

 

'Swift information' 카테고리의 다른 글

우아한 Model Data 처리 (1)  (0) 2022.06.11
클로저 - Capturing Values와 ARC  (0) 2021.12.03
ARC 시리즈 2 - SideTable  (0) 2021.11.04
ARC 시리즈 1 - Retatin Cycle 과 Reference Count  (0) 2021.11.02
    'Swift information' 카테고리의 다른 글
    • 우아한 Model Data 처리 (1)
    • 클로저 - Capturing Values와 ARC
    • ARC 시리즈 2 - SideTable
    • ARC 시리즈 1 - Retatin Cycle 과 Reference Count
    iJoom
    iJoom

    티스토리툴바