ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift #11 - 메모리 관리
    Swift의 온도 2021. 1. 19. 01:23

     

    1. ARC와 메모리 관리

     

    - 객체 생성과 메모리

    #객체 생성 -> 메모리 차치

    #메모리 공간의 제약 -> 메모리 관리

     

    #메모리관리

     *필요한 객체 유지

     *필요 없는 객체 해재

     

    #객체가 사용 중인가?

     *사용중이라는 표시 - 소유하기(Own)

     *객체 소유하는 방법 - 강한 참조(Strong pointer)

     

    - 객체 소유 관리

    #레퍼런스 카운트(Reference Count)

     *강한 참조의 개수

     *객체 사용 -> 레퍼런스 카운트 늘리기

     *객체 사용 끝 -> 레퍼런스 카운트 감소

     *레퍼런스 카운트 0 : 객체 사용 끝

     

    #레퍼런스 카운트 관리

     *수동 관리 : 레퍼런스 카운트 증가/감소 코드 작성

     *자동 관리 : 레퍼런스 카운트 증가/감소 자동

     

    - ARC

    #Automatic Reference Counting

    #자동 레퍼런스 카운트 관리

    #객체의 레퍼런스 카운트 관리 코드 자동 생성

    #레퍼런스 타입(클래스) 객체에만 적용

    #밸류 타입(구조체, Enum) 객체에는 미적용

     

    - 객체 소유하기, 소유권 해제

    #객체 생성과 해제 확인

    *객체 생성 : 객체 소유
     
    var ptr : MyClass! = MyClass()
     
    *nil 대입 : 소유권 해제
     
    ptr = nil
    cs

     *레퍼런스 카운트 0 : 객체 해제

     

    #객체 해제 확인하기

    *클래스의 deinit 메소드 작성
    *프로젝트 환경에서 동작
     
    class MyClass {
        deinit {
            print("객체가 메모리에서 해제")
        }
    }
     
    * 객체 생성과 해제 확인
    cs

     

    #강한 참조

    *객체를 소유하는 포인터
    *소유권 해제가 객체의 해제는 아니다.
    *다른 참조를 이용해서 소유하기
     
    var obj : MyClass! = MyClass()
     
    var anotherPointer = obj
     
    obj = nil
    cs

     

    - 변수의 스코프와 소유권

    #객체를 소유하는 참조 변수의 종류

     *지역 변수

     *프로퍼티

     *타입 프로퍼티

     

    #선언 방식에 따라 스코프(Scope)가 다르다.

     

    - 지역 변수, 소유권

    #참조 변수 : 지역변수

    *함수 내 지역 참조 변수의 스코프 : 함수 범위
    *함수 종료와 함께 소유권 해제
     
    class MyApplication {
        func sayHello(){
            var obj : MyClass!
            obj = MyClass()
     
            print("Hello World!")
        }
    }
    cs

     

    - 프로퍼티와 소유권

    #참조 변수 : 프로퍼티

    *프로퍼티의 라이프 사이클 : 객체 생명 주기
     
    class MyApplication {
        var obj : MyClass!
        init(){
            obj = MyClass()
        }
        func hello(){
            obj.howAreYou()
        }
    }
    cs

     

    - 타입 프로퍼티

    #참조 변수 : 타입 프로퍼티

    *객체의 생존 주기와 무관
     
    class MyApplication {
        static var obj : MyClass!
    }
     
    *수동으로 객체 생존 주기 설정
     
    MyApplication.obj = MyClass()
    MyApplication.obj = nil
    cs

     

    - 콜렉션과 소유권

    #콜렉션에 객체 저장 : 콜렉션이 객체 소유

    #콜렉션에서 객체 삭제 : 소유권 해제

    #콜렉션 객체 해제 : 소유권 해제

    *메모리 소유권 해제 실습
     
    var obj : Myclass! = MyClass()
    var array = [obj]
    obj = nil
     
    *배열에서 삭제 - 소유권 해제
     
    array.remove(at.0)
    cs

     

    2. 강한 순환 참조

     

    - 강한 참조로 순환 참조

    #두 개 이상의 관계에서도 가능

    #서로 소유하므로 해제되지 않음(메모리 누수)

    #수동으로 해제되도록 작성해야 함

    #정상 해제 상황

    class ClassA {
        var objB : ClassB!
        deinit { print("A 객체 해제") }
    }
    class ClassB {
        var objA : ClassA!
        deinit { print("B 객체 해제")}
    }
    var a : ClassA! = ClassA()
    var b : ClassB! = ClassB()
     
    = nil
    = nil
    cs

     

    - 강한 순환 참조 확인

    #강한 순환 참조 발생

    class ClassA {
        var objB : ClassB!
        deinit { print("A 객체 해제") }
    }
    class ClassB {
        var objA : ClassA!
        deinit { print("B 객체 해제")}
    }
    var a : ClassA! = ClassA()
    var b : ClassB! = ClassB()
    a.objB = b
    b.objA = a
    = nil, b = nil
    cs

     

    3. 약한 참조

     

    - 강한 참조, 약한 참조

    #강한 순환 참조 문제 해결하기

     *객체를 소유하는 강한 참조만 사용하면 문제가 될 수 있음

     *객체를 소유하지 않는 약한 참조(Weak reference) 사용

     

    #약한 참조

     *객체를 소유하지 않는 포인터 : weak, unowned

     

    - 약한 참조

    #weak

     *참조하던 객체가 해제되면 자동 nil

     *nil이 되므로 옵셔널

     *상호 독립적으로 존재하는 객체에 사용

     

    #권장 사용 예시

     *사용자와 스마트폰

     *운전자와 자동차

     

    - 약한 참조 예시

    *클래스 작성
     
    class Person {
        weak var phone : Phone!
        deinit { print("Person 객체 해제") }
    }
    class Phone {
        var owner : Person!
        deinit { print("Phone 객체 해제") }
    }
     
    *사용
     
    var owner : Person! = Person()
    var iphone : Phone! = Phone()
    iphone.owner = owner
    owner.phone = iphone
    // 객체 해제 확인
    owner = nil; iPhone = nil
    cs

     

    - unownned

    #옵셔널 타입으로 선언 불가(Initializer)

    #완전히 종속적인 경우에 사용

    #참조하던 객체가 해제되도 nil로 변하지 않음 -> Dangling pointer 위험

    #단독으로 존재 못하는 종속적인 경우

     

    #권장 사용 예시

     *신용카드와 사용자

     *국가와 수도

    *클래스 작성
     
    class Country {
        var capital : City!
    }
    class Capital {
        unowned var country : Country
        init(country:Country) {
            self.country = country
        }
    }
     
    *사용
     
    var korea : Country! = Country()
    var seoul : Capital! = Capital(country:korea)
    korea.capital = seoul
    // 객체 해제 확인
    korea = nil; seoul = nil
    cs

    'Swift의 온도' 카테고리의 다른 글

    Swift #13 - 클로저  (0) 2021.01.21
    Swift #12 - 구조체와 Enum  (0) 2021.01.20
    Swift #10 - 상속  (0) 2021.01.15
    Swift #9 - 객체 초기화  (0) 2021.01.14
    Swift #8 - 클래스  (0) 2021.01.13

    댓글