05.12 (월) iOS 사전캠프

2025. 5. 12. 20:23·🖋️ TIL Journal
-->
TIL은 편한 말투로 작성됩니다~

 

📍 오늘의 학습 내용
- 프로그래머스(수열과 구간 쿼리 3) 문제 풀이
- 자료구조/메모리 구조 및 ARC 

 

아래는 공부하며 정리한 것들을 정리한 주소이다.

- 자료구조/메모리 구조 및 ARC (공부 정리)
- 자료구조/메모리 구조 및 ARC (문제 풀이)

 

 

 

✅ [프로그래머스 문제 풀이]


오늘은 프로그래머스 - 수열과 구간 쿼리3 문제를 풀었다.

 

이 문제는 주어진 정수 배열에서 각 쿼리마다 두 인덱스의 값을 서로 바꾸는 작업을 수행한 뒤에 최종 배열을 반환하는, 단순한 스왑 연산(swapAt(_:_:))을 반복하는 구현문제였다.

 

작성한 코드 (for 문 사용)
import Foundation

func solution(_ arr:[Int], _ queries:[[Int]]) -> [Int] {
    var arr = arr
    for query in queries {
        arr.swapAt(query[0], query[1])
    }
    return arr
}

 

처음에는 위와 같이 for문을 사용하여 코드를 작성하였다.

 

그런데, 문제를 풀다가 느낀 건데 다른 사람들의 코드를 보니, forEach 문이나 고차함수를 많이 사용하는구나 싶은 생각이 들었다.

 

익숙하지 않으면 필요할 때도 자연스럽게 떠올리지 못할 것 같기에, 앞으로 문제를 풀면 고차함수와 forEach문을 사용해서도 한 번 풀어보자. 라는 생각에 오늘은 아래처럼 forEach문을 사용한 코드도 작성해 보았다.

 

forEach문을 사용한 코드
import Foundation

func solution(_ arr:[Int], _ queries:[[Int]]) -> [Int] {
    var arr = arr
    queries.forEach { arr.swapAt($0[0], $0[1]) }
    
    return arr
}

문제를 풀고 보니, 많은 사람들이 아래의 forEach문 코드와 거의 동일하게 많이 작성했다. 난 아직 for문이 더 편한 거 같은데.. 익숙해지면 forEach문을 더 많이 쓰게 되려나...?

 

 

 

 

💻 [자료구조/메모리 구조 및 ARC]


아래는 위에 작성한 자료구조/메모리 구조 및 ARC의 일부분이다. 공부하며 인상 깊었거나, 새롭게 공부한 부분만 일부 가져왔다.

 

 

📍 ARC(Automatic Reference Counting)

  • Swift의 메모리 관리 방식
  • 클래스 인스턴스의 참조 횟수를 추적하여, 더 이상 필요하지 않은 인스턴스를 자동으로 메모리에서 해제
  • 하지만, ARC에는 한 가지 제한점이 있다. -> 바로.. 순환 참조(Circular Reference)!
    • 두 개 이상의 인스턴스가 서로를 강하게 참조할 경우
    • 참조 횟수가 0이 되지 않아 메모리에서 해제되지 않는 문제가 발생하게 됨
    • 🔧 해결 방법: weak 또는 unowned 키워드를 사용하여 강한 참조를 피함

 

순환 참조 예제
class Person {
   var name: String
   var pet: Pet?
	
   init(name: String) {
      self.name = name
   }
}

class Pet {
   var owner: Person?
}

let person = Person(name: "Mori")
let pet = Pet()

person.pet = pet
pet.owner = person // 순환 참조 발생

 

위 코드에서 person은 pet을 강하게 참조하고, pet 또한 owner 프로퍼티를 통해 person을 강하게 참조함.

 

이처럼 서로를 강하게 참조하면, 두 인스턴스 모두 참조 횟수(Reference Count)가 0이 되지 않아 ARC가 메모리에서 해제할 수 없게 됨.

 

이 상황을 바로 위에서 말한 순환 참조(Circular Reference)라고 한다.

 

해결 방법
class Pet {
   weak var owner: Person?
}

해결 방법은 weak 즉, "약한 참조(Weak Reference)"를 사용하는 것이다.

 

weak(약한 참조)를 사용하면 owner가 person을 참조하되, 참조 횟수를 증가시키지 않기 때문에 순환 참조를 방지할 수 있다.

 

이제 person이 더 이상 사용되지 않으면, ARC가 person과 pet 인스턴스를 정상적으로 메모리에서 해제할 수 있게 된다.

 

 

 

💡 weak vs unowned


weak와 unowned 둘 다 "약한 참조(Weak Reference)" 방식으로, ARC에서 발생할 수 있는 순환 참조(Circular Reference)를 방지하여 메모리 누수를 막는 것이 공통된 목적이다.

 

  • ✅ 공통점
    • 참조하고 있는 인스턴스의 참조 카운트를 증가시키지 않음
    • 순환 참조를 끊는 용도로 사용
    • ARC에서 객체가 해제될 수 있도록 돕는다.

 

weak 먼저 보자!
class Person {
   var pet: Pet?
}

class Pet {
   weak var owner: Person? // 반드시 Optional
}

 

weak 참조는 참조 대상이 해제되면, ARC가 해당 변수를 자동으로 nil을 할당하기에, weak는 항상 Optional로 선언되어야 한다.

 

unowned 그럼 넌 뭐야?
class Person {
   var pet: Pet?
}

class Pet {
   unowned var owner: Person // Non-Optional
}

unowned는 Optional이 아니며, 참조 대상이 절대 먼저 해제되지 않는다는 보장이 있을 때만 사용해야한다.

 

만약에 보장이 지켜지지 않고 참조 대상이 먼저 메모리에서 해제된다면, 존재하지 않는 메모리를 참조하려 했기에 런타임 에러가 발생한다.

 

 

 

unowned가 어울리는 상황

class Customer {
   var card: CreditCard?
}

class CreditCard {
   unowned let owner: Customer // 고객이 먼저 사라질 일이 없음
}

 

CreditCard는 항상 Customer가 있을 때만 존재하므로, unowned 사용이 적절하다. (한 쪽이 사라질 일 없다는 확신이 있을 때 사용)

 

 

 

💡deinit 메서드란?

  • deinitializer(소멸자)의 줄임말
  • 클래스 인스턴스가 ARC에 의해 더 이상 참조되지 않게 되면, 메모리에서 해제되며 이때 deinit이 실행된다.
  • 주로 리소스 정리, 순환 참조 확인, 디버깅 로그 출력 등에 사용된다고 한다.
  • 구조체는 ARC로 관리되지 않기 때문에, deinit이 없다. (오직 Class에서만 사용 가능)
class MyClass {
   deinit {
      print("My Class 인스턴스가 메모리에서 해제됩니다.")
   }
}

 

위에도 작성했던 자료구조/메모리 구조 및 ARC(문제 풀이)의 링크에 "Step 2: ARC와 순환 참조 해결" -> "2. 순환 참조 해결"을 보면, deinit을 사용하여 문제를 푼 예시가 있다.

 

 

🙌 학습하며 느낀 점
weak는 공부했었지만, unowned와 deinit은 이번에 처음 접했다.
특히 deinit를 사용하면 값이 메모리에서 해제되는 시점을 직접 확인할 수 있어서, 개발할 때 굉장히 중요한 부분이겠다고 생각했다.

 

'🖋️ TIL Journal' 카테고리의 다른 글

05.14 (수) iOS 사전 캠프  (0) 2025.05.14
05.13(화) iOS 사전 캠프  (0) 2025.05.13
05.08 (목) iOS 사전 캠프  (0) 2025.05.08
05.07 (수) iOS 사전 캠프  (0) 2025.05.07
05.02 (금) iOS 사전 캠프  (1) 2025.05.02
'🖋️ TIL Journal' 카테고리의 다른 글
  • 05.14 (수) iOS 사전 캠프
  • 05.13(화) iOS 사전 캠프
  • 05.08 (목) iOS 사전 캠프
  • 05.07 (수) iOS 사전 캠프
MoriOS
MoriOS
기억하기 위해 기록하는 공간 🖋️
  • MoriOS
    MoriOS
    MoriOS
  • 전체
    오늘
    어제
    • 분류 전체보기 (36) N
      • 📌 Swift (10)
      • 📱 iOS (4)
      • 💡 Algorithm (1)
      • ❕Data structure (4)
      • 🪙 Python (0)
      • ⚙️ Git (2)
      • 🖋️ TIL Journal (12) N
      • 📝 Etc (3)
  • 블로그 메뉴

    • GitHub
  • 인기 글

  • 태그

    Split
    터미널 기본 경로
    swift 알고리즘 팁
    ios 데이터 저장
    TiL
    weak vs unowned
    터미널 워킹 디렉토리
    낼배캠 사전 캠프
    swift
    후행클로저
    swift 최대 최소
    ios segue
    todo앱
    swift 아스키
    swift ismultiple
    swift 수학
    iterm 실행 폴더
    ios
    todo 앱
    swift 대소문자
    Optional
    swift min
    joined()
    Components
    weak
    swift optional
    낼배캠
    iterm2 기본 경로
    swift max
    강한 참조
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
MoriOS
05.12 (월) iOS 사전캠프
상단으로

티스토리툴바