스토리보드와 인터페이스 빌더를 이용한 뷰 생성시 질문 있습니다.

1 답변 글타래를 보이고 있습니다
  • 글쓴이
    • 광현
      참가자
      • 글작성 : 15
      • 답글작성 : 26

      스토리보드를 통한 UI 생성에도 익숙해지고자 스토리보드를 공부하던 도중, @IBOutlet weak var: …를 쓰는 것에 처음에는 의문이 없었지만 weak 키워드를 쓰는 것에 의문이 생겼습니다. ARC(자동 참조 계수)와 깊은 연관이 있다는 것을 알게 되어 공부 중에 있습니다.

      참조 링크1

      참조 링크2

      1. 스토리보드에서 UIObject를 생성했을 때, 스토리보드 내에서 해당 UIObject의 인스턴스가 생성되는 것인지 궁금합니다.
      2. 그렇다면 ViewController는 @IBOutlet 변수 또는 상수를 통해 접근하는 것으로 이해했습니다. 그리고 weak으로 선언하는 이유가 위의 사이트를 참조하고 생각해 본 결과 strong 참조 (강한 참조)를 하게 되면 ViewController 와 View 간에 서로를 참조하는 관계?(맞는 표현인지는 모르겠습니다.) 다른 분의 블로그에서는 서로 멱살을 잡은 상태라고 표현하는 상태라고 생각하는 데 틀린 부분이 있다면 알고 싶습니다.
      3. 위 참조 사이트 중 하나에서는 strong 으로 해도 오류는 발생하지 않는다는 문구가 있었습니다. 다만 필요에 따라 weak, unowned, strong 을 구분해서 써야한다고 알고 있습니다. 혹시 그 구분 방법이 있는지 알고 싶습니다.
      • 이 게시글은 광현에 의해 4 years 전에 수정됐습니다. 이유: 줄 바꿈 고침
    • 야곰
      키 마스터
      • 글작성 : 37
      • 답글작성 : 580
      1. 스토리보드에서 생성되는 것은 아닙니다. 앱이 실행되어 뷰를 스토리보드에서 불러오는 순간, 스토리보드에 구성해 놓은 모양대로 그 때 뷰의 인스턴스가 생성되어 동작하게 됩니다. 즉, 스토리보드에는 어떤 뷰 클래스의 뷰가 어디에 위치할지 등의 정보만 담아두고, 실제로 뷰 클래스의 인스턴스가 생성되는 시점은 스토리보드로부터 뷰 구성 정보를 불러와서 화면에 보여주려 할 때(앱 동작 중)입니다. 그래서 뭔가 런타임 오류 발생여지가 있어도 스토리보드에서는 직접 오류가 발생하지 않고, 실행해서 화면이 보여지려고 하는 순간 오류로 앱이 죽죠. 스토리보드는 앱 동작 전에 이미 만들어져있으므로 스토리보드에 직접 인스턴스가 생성된다고 볼 수는 없습니다. 그저 우리 눈에 그렇게 보이는것 뿐입니다.
      2. `@IBOutlet`은 변수만 가능합니다. 상수는 불가능합니다. 그 이유는 위의 설명과 연관있는데요, 이미 `@IBOutlet` 프로퍼티가 메모리에 생성된 후에 동적으로 스토리보드 정보로부터 만들어진 인스턴스를 `@IBOutlet` 프로퍼티에 할당해야 하기 때문입니다. 그런데 해당 프로퍼티가 상수면 변경(할당)이 불가하기 때문에 항상 변수(`var`)여야 합니다.
        • 통상 처음 배우는 분들은 뷰 컨트롤러의 view 위에 얹어지는 subview를 `@IBOutlet` 프로퍼티로 지정하므로 그 기준으로 설명하겠습니다. 뷰 컨트롤러의 뷰 위에 얹어지는 자식뷰를 `@IBOutlet` 프로퍼티에 `strong`으로 할당되면 retain count가 1 증가합니다. 그리고 어딘가의 자식 뷰로 얹어지면 retain count가 1 추가로 증가합니다. 그래서 뷰컨트롤러의 view 위에 얹어진 자식뷰의 retain count는 `@IBOutlet`이 `strong` 프로퍼티인 경우 기본적으로 retain count가 2입니다. 꼭 서로 멱살잡고 있는 구조는 아닙니다… 서로 멱살잡고 있는 모습은 순환참조 문제인데, 이 문제는 순환참조 문제에 해당하지 않습니다.
      3. 위의 설명처럼 `strong`으로 해도 전혀 오류는 발생하지 않습니다. 다만 자식뷰가 부모뷰에서 떨어져 나와도 retain count가 1이 남아있으므로 뷰컨트롤러가 메모리에서 해제되기 전까지 @IBOutlet 변수의 뷰는 메모리에서 해제되지 않습니다(물론 부모 뷰에서 떨어져나온 후 아웃렛 변수에 `nil`을 할당하면 메모리에서 해제됩니다. 이해가 안가면 ARC 조금 더 공부하면 좋습니다). 이를 의도하고 `strong`으로 할당한다면 괜찮습니다. 가령 경우에 따라서 해당 뷰를 부모 뷰에 붙였다 뗐다 해야 하는 경우엔 유용합니다. 하지만 이것도 뷰를 직접 뗐다(`removeFromSuperview`) 붙였다(`addSubview:`) 보다는 그냥 뷰를 잠깐 안보이게 hidden하는 방법이 있습니다. 이때는 부모 뷰에서 실질적으로 떨어져 나온 것이 아니기 때문에 retain count의 변화는 없습니다. 그래서 통상 의도적인 목적이 없는 경우에는 `@IBOutlet` 변수를 `weak`로 선언하여 아웃렛 인스턴스의 retain count를 1로 만들어줍니다. 부모 뷰에서 떨어져 나오면 retain count가 0이 되므로 바로 메모리에서 해제되죠.

      위 내용을 검증하고 싶다면 아래 클래스를 @IBOutlet 변수의 클래스로 지정해 준 후에 strong으로 할당한 후 실행했을 때, 아웃렛 변수에 해당하는 뷰를 부모 뷰에서 떼어내면(removeFromSuperview) deinit이 호출되지 않아요. 반대로 weak로 할당한 후에 실행하면 removeFromSuperview 이후엔 deinit이 호출되는 것을 확인할 수 있을겁니다.

      class MyView: UIView {
        deinit {
          print("뷰가 메모리에서 해제됨")
        }
      }
      

      • 이 답변은 야곰에 의해 4 years 전에 수정됐습니다.
      • 이 답변은 야곰에 의해 4 years 전에 수정됐습니다.
      • 이 답변은 야곰에 의해 4 years 전에 수정됐습니다.
      • 광현
        참가자
        • 글작성 : 15
        • 답글작성 : 26

        긴 답변글 작성해주셔서 정말 감사합니다.

        답변 덕분에 스토리보드의 작동원리에 대해서 의문점이 풀렸습니다.

        그리고 ARC 와 그 연관문제인 순환참조, 그리고 deinit 결과는 공부하고 직접 해보도록 하겠습니다. 그 후에도 막히거나 궁금한 게 있다면 다시 질문 드리도록 하겠습니다.

        즐거운 주말 보내시길 바랍니다. 👍

        • 야곰
          키 마스터
          • 글작성 : 37
          • 답글작성 : 580

          네, 답변을 쓰다보니 길어졌네요.. 횡설수설 한 것 같기도..! 추가적으로 또 궁금한게 있으면 언제든 말씀하세요~

      • 멍단비
        참가자
        • 글작성 : 10
        • 답글작성 : 98

        덕분에 버스타서 같이 공부 좀 했네요. 감사합니다.

        추가로 공식문서 링크도 설명이 잘 나와있는 것 같아서 참고하시라고 첨부합니다.

        https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html

        <p style=”color: red !important;”>파이팅하세요~</p>

        @yagom
        이거 왜 안될까요..?

        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
        • 야곰
          키 마스터
          • 글작성 : 37
          • 답글작성 : 580

          에디터 스타일을 텍스트 모드로 해보실래요? 비주얼 모드에서는 수동 HTML코드가 잘 안먹는거 같아요… 이미 자동으로 p 태그가 매겨져서..

          • 멍단비
            참가자
            • 글작성 : 10
            • 답글작성 : 98

            에디터 스타일 모드를 바꾸는 법을 못찾겠어서..;; 삽질을 좀 했어요.

            다행히 찾았습니다. 이유는 잘 모르겠지만, 빨강으로 강조를 하려면 상단 메뉴중에 CODE를 선택하면 되네요.

            요런식으로요. 아니면 백틱?백쿼트?을 강조를 원하는 글자 양옆에 붙여주면 되는 것 같아요.

            수정만 겁나 했네요.. 후덜 ㅎㅎ.. 이거 수정 가장 최근거 하나만 보여주는 것도 나쁘지 않을 것 같은..? 너무 길어져서 ㅎㅎ

            • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
            • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
            • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
            • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
            • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
            • 이 답변은 멍단비에 의해 4 years 전에 수정됐습니다.
1 답변 글타래를 보이고 있습니다
  • 답변은 로그인 후 가능합니다.

logo landscape small

사업자번호 : 743-81-02195
통신판매업 신고번호 : 제 2022-충북청주-1278 호
고객센터 : 카카오톡채널 @yagom