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

[220905] TIL #122

Open
Taehyeon-Kim opened this issue Sep 5, 2022 · 2 comments
Open

[220905] TIL #122

Taehyeon-Kim opened this issue Sep 5, 2022 · 2 comments
Assignees

Comments

@Taehyeon-Kim
Copy link
Owner

Taehyeon-Kim commented Sep 5, 2022

ARC

메모리 구조

  • 코드 : 우리가 작성하는 코드가 들어가는 영역
  • 데이터 : 전역적으로 쓰일 수 있는 변수 (타입 프로퍼티)
  • 힙 : ARC가 관리하는 영역, 클래스의 경우 인스턴스를 생성(인스턴스를 생성, 제거할 때마다 메모리에 올렸다가 내렸다가 하는 과정 필요)
  • 스택

ARC

  • Auto Reference Counting

RC (참조 횟수)

  • Reference Count
  • 인스턴스 생성 -> 메모리에 올라갔다. -> RC+1
  • 인스턴스 해제 -> 메모리에서 내려갔다. -> RC-1
  • RC == 0 인 시점에 힙영역에서 내린다. (=메모리 해제)

생성/해제

var user: User? = User(name: "고래밥") // User: RC 1
var guild: Guild? = Guild(name: "SeSAC") // Guild: RC 1

guild = nil // Guild: RC 0
user = nil // User: RC 0

/*
User init
Guild init
Guild deinit
User deinit
*/
var user: User? = User(name: "고래밥") // User: RC 1
var guild: Guild? = Guild(name: "SeSAC") // Guild: RC 1

user?.guild = guild // Guild: RC 2
guild?.owner = user // User: RC 2

guild = nil // Guild: RC 1
user = nil // User: RC 1

/*
User init
Guild init
*/

// ==> 순환 참조 발생

해결

순환 참조인 녀석을 먼저 nil

var user: User? = User(name: "고래밥") // User: RC 1
var guild: Guild? = Guild(name: "SeSAC") // Guild: RC 1

user?.guild = guild // Guild: RC 2
guild?.owner = user // User: RC 2

guild?.owner = nil // User: RC 1

guild = nil // Guild: RC 1
user = nil // User: RC 0 -> user deinit -> Guild: RC 0

/*
User init
Guild init
User deinit
Guild deinit
*/

수동으로 해결하기 어렵다.

  • 관계 다 찾아서 해결할 수 있겠니?
  • 아뇨
  • 그래서 쉽게 해결할 수 있는 방법을 준비했단다.

weak, unowned keyword

  • weak : RC를 증가시키지 않는다.
    • ex. IBOutlet 부분
    • 수명(RC로 파악)이 더 짧은 인스턴스를 가리키는 녀석을 약한 참조(weak)로 선언하자
  • unowned : RC를 증가시키지 않는다.

ARC + delegate

  • delegate를 사용할때는 weak를 필수적으로 써주어야 함.
  • 뷰 컨트롤러가 생성되고 해제되는 문제를 해결해주어야 함.
  • weak 키워드를 경우에는 결국 class에서 사용을 제한해주어야 하기 때문에 AnyObject로 제약을 걸어주어야 함.
protocol MyDelegate: AnyObject {
    func sendData(_ data: String)
}
protocol BDelegate: AnyObject {
  func method()
}

class A: BDelegate {

  lazy var b: B = {
    let view = B()
    view.delegate = self
    return view
  }()

  func method() {
    // code
  }

}

class B {

  weak var delegate: BDelegate?

  func dismiss() {
    delegate?.method()
  }

}

// var A: A? = A()
// A?.b
// A.nil

/*
weak키워드로 참조를 약하게 만들지 않으면 A, B의 인스턴스는 해제되지 않는다.
*/

ARC + Closure

import UIKit

class User {
    var nickname = "JACK"
    
    lazy var introduce: () -> String = { [weak self] in
        return "저는 \(String(describing: self?.nickname))입니다."    // self로 접근하기 때문에 순환 참조 발생
    }

    init() {
        print("User init")
    }
    
    deinit {
        print("User deinit")
    }
}

var user: User? = User()
user?.introduce()       // RC + 1
user = nil

// User init
// User deinit

값 캡처

  • 호출시에 값이 캡처된다.
func myClosure() {
    
    var number = 0
    print("1: \(number)")
    
    let closure: () -> Void = { [number] in  // 값 캡처, 값 타입 - 복사, 클로저 안에서는 값이 영향을 받지 않는다.
        print("closure: \(number)")
    }
    
    closure()
    
    number = 100
    print("2: \(number)")
    
    closure()
}

myClosure()

/*
1: 0
closure: 0
2: 100
closure: 0
*/
@Taehyeon-Kim Taehyeon-Kim self-assigned this Sep 5, 2022
@Taehyeon-Kim
Copy link
Owner Author

Taehyeon-Kim commented Sep 5, 2022

Swift에서 메모리를 어떻게 하죠?

  • MRC -> ARC
  • 참조에 대한 차이로 strong, weak, unowned가 존재한다.

weak와 unowned의 차이는 무엇인가?

Taehyeon-Kim added a commit that referenced this issue Sep 5, 2022
Taehyeon-Kim added a commit that referenced this issue Sep 5, 2022
@Taehyeon-Kim
Copy link
Owner Author

메모리에서 인스턴스가 해제되었는지 어떻게 아나요?

  • deinit으로 확인해본다.

Taehyeon-Kim added a commit that referenced this issue Sep 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant