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

순환 참조는 언제 일어나며, 해결방법은 무엇인가요? #27

Open
youn9k opened this issue Jan 4, 2025 · 3 comments
Open

Comments

@youn9k
Copy link
Collaborator

youn9k commented Jan 4, 2025

  • 강한 순한 참조를 통해서 서로가 서로를 참조하여 RC가 0이 되지 않는 상황에서 발생할 수 있음.
  • ARC가 RC를 기준으로 작동한다. 이를 해결하기 위해 weak, unowned을 사용하여 RC를 증가시키지 않는 방식으로 해결할 수 있다.
  • weak, unowned 차이점 가볍게 설명
    • 참조 인스턴스가 메모리에서 해제될 때 weak는 nil이 할당됨
    • unowned는 수명이 긴 인스턴스를 확신하고 사용해야함.
@hsw1920
Copy link
Owner

hsw1920 commented Jan 10, 2025

Q. 순환 참조는 언제 일어나는지 설명해주세요.
A.
강한 순환 참조는 두 개 이상의 인스턴스가 서로를 강하게 참조하여 변수에 인스턴스를 할당하여 생기는 참조 카운트(RC) 이외에 서로가 참조하여 추가로 참조 카운트(RC)가 증가하여 nil을 할당하더라도 참조 카운트(RC)가 0이 되지 않아 메모리에서 해제되지 않아 메모리 누수 현상이 발생하여 문제가 발생합니다.

Q. 해결방법은 무엇인가요?
A.
이를 해결하기 위해서는 약한 참조(weak) 또는 미소유 참조(unowned)를 통해서 참조 카운트(RC)의 증가를 발생시키지 않는 방식으로 해결할 수 있습니다.

수명이 더 짧은 참조 인스턴스에게 약한 참조(weak)를 붙이거나, 수명이 더 긴 참조 인스턴스에 미소유 참조(unowned)를 붙이는 방식으로 이를 해결합니다.

약한 참조(weak)를 통해 수명이 짧은 인스턴스가 먼저 메모리에서 해제되더라도 자동으로 nil이 할당되어 에러를 막을 수 있습니다. 반면 미소유 참조(unowned)의 경우 먼저 메모리에서 해제되지 않는다는 것을 확신하고 사용하기 때문에 옵셔널로 사용되지 않으며 주의하며 사용해야합니다. 만약 미소유 참조(unowned) 키워드를 붙인 참조 인스턴스가 메모리에서 해제된 후 해당 인스턴스를 참조하게 되면 에러가 발생하기 때문에 수명이 더 긴 인스턴스를 확신하고 미소유 참조(unowned) 키워드를 사용해야 합니다.

답변의도

  • 순환 참조가 발생하는 원인을 설명한다.
  • 해결 방법인 weak, unowned 키워드의 동작 방식의 차이점을 설명한다.

@0Hooni
Copy link
Collaborator

0Hooni commented Jan 11, 2025

순환 참조는 두 개 이상의 객체가 서로를 강한 참조로 참조하여 발생하는 문제입니다. 이러한 순환참조는 메모리 누수를 유발하여 메모리 사용 효율성을 저하시키게 됩니다.

순환 참조를 해결하기 위해서는 이러한 강한 참조 연결고리를 끊어주어야 됩니다. 대표적인 방법으로는 약한 참조로 변경하는 방식이 있습니다.

약한 참조를 사용하게 되면 참조 카운트를 증가시키지 않고, 참조 대상이 해제되면 자동으로 nil로 설정되기에 순환 참조로 인한 메모리 누수 문제를 쉽게 해결할 수 있습니다.

@Kiyoung-Kim-57
Copy link
Collaborator

순환 참조는 두 개의 객체가 서로 강한 참조를 하고 있을 때 일어납니다.

더 자세히 말하자면 ARC 시스템에서 강한 참조를 하게 되면 참조 카운트가 1이 증가하게 됩니다. 이 카운트는 참조 대상이 메모리에서 해제되면 줄어들게 되고 참조 카운트가 0이 되면 객체가 메모리에서 해제됩니다.
순환 참조는 두 객체가 서로를 강한 참조를 하고 있기 때문에 참조 카운트가 0이 되지 않아 메모리에서 해제되지 않고 이는 메모리 누수를 유발합니다.
예를 들어 A,B가 서로를 강한 참조를 하고 있다면 A는 B의 해제를 기다리고 B는 A의 해제를 기다리는 교착 상태가 됩니다.

순환 참조를 해결하기 위한 방법으로는 강한 참조 대신 weak, unowned 참조를 사용하는 방법이 있습니다. 두 참조는 참조 카운트를 증가시키지 않아 상호 참조 상태에서도 정상적으로 메모리 해제가 가능합니다.
다만 unowned 참조의 경우 참조 대상이 메모리에서 해제될 경우 runtime crash가 발생하기 때문에 조심해서 사용해야 하고 메모리에서 해제가 될 여지가 있는 참조는 weak참조를 하는 것이 좋습니다. weak은 참조 대상이 해제될 경우 자동으로 Nil을 할당합니다.

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

4 participants