Swift로 Reference Type과 ARC 활용한 프로퍼티 Assign 방법

작성일 :

Swift로 Reference Type과 ARC 활용한 프로퍼티 Assign 방법

Swift는 강력하고 직관적인 프로그래밍 언어로, 특히 메모리 관리를 위한 자동 참조 카운팅(Automatic Reference Counting, ARC)을 통해 개발자가 메모리 관리를 쉽게 할 수 있도록 돕습니다. 이 글에서는 Swift에서 Reference Type을 활용해 프로퍼티를 할당하며, ARC가 어떻게 작동하는지에 대해 자세히 설명합니다.

Reference Type과 Value Type의 차이

Swift는 값을 저장하고 전송할 때 두 가지 방법, 즉 Reference TypeValue Type을 제공합니다. 이 두 가지 타입은 메모리에 어떻게 저장되고 참조되는지에 큰 차이가 있습니다.

Value Type

Value Type은 변수를 다른 변수에 할당할 때, 값을 복사해서 전달합니다. Swift의 기본 데이터 타입(Int, Float, Double 등) 및 구조체(struct)는 모두 Value Type입니다. 예를 들어, 아래 코드를 봅시다:

swift
struct Point {
    var x: Int
    var y: Int
}

var point1 = Point(x: 0, y: 0)
var point2 = point1
point2.x = 10

print(point1.x) // 0 

여기서 point1point2에 할당할 때, point2는 독립적인 복사본이 됩니다. 따라서 point2의 값을 변경해도 point1에 영향을 주지 않습니다.

Reference Type

Referece Type은 변수를 다른 변수에 할당할 때, 동일한 인스턴스를 참조하게 됩니다. Swift의 클래스(class)는 Reference Type입니다. 예를 들어, 아래 코드를 봅시다:

swift
class Point {
    var x: Int
    var y: Int
    init(x: Int, y: Int) {
        self.x = x
        self.y = y
    }
}

var point1 = Point(x: 0, y: 0)
var point2 = point1
point2.x = 10

print(point1.x) // 10

여기서 point1point2에 할당할 때, 둘 다 동일한 인스턴스를 참조하게 됩니다. 따라서 point2의 값을 변경하면 point1도 영향을 받게 됩니다.

ARC(Automatic Reference Counting)

ARC는 Swift에서 메모리 관리를 자동화하는 기능으로, Reference Type의 인스턴스가 더 이상 필요하지 않을 때 메모리에서 자동으로 해제합니다. ARC는 강한 참조(strong reference)와 약한 참조(weak reference), 미약 참조(unowned reference)라는 세 가지 유형의 참조를 사용하여 메모리를 관리합니다.

강한 참조(Strong Reference)

기본적으로 모든 참조는 강한 참조입니다. 강한 참조는 인스턴스의 참조 카운트를 증가시켜, 인스턴스가 참조될 때마다 ARC가 인스턴스를 메모리에 유지합니다. 예를 들어:

swift
class Person {
    var name: String
    var bestFriend: Person?
    init(name: String) {
        self.name = name
    }
}

var john: Person? = Person(name: "John")
var doe: Person? = Person(name: "Doe")

john?.bestFriend = doe

여기서는 johndoe가 서로를 강하게 참조하고 있어, 두 객체는 서로 없애지 않는 한 메모리에 계속 남아 있게 됩니다.

약한 참조(Weak Reference)

약한 참조는 인스턴스의 참조 카운트를 증가시키지 않습니다. 즉, 인스턴스가 다른 강한 참조가 없으면 메모리에서 해제될 수 있습니다. 약한 참조는 optional 타입이어야 하며, 메모리 해제 시 자동으로 nil로 설정됩니다. 예:

swift
class Person {
    var name: String
    weak var bestFriend: Person?
    init(name: String) {
        self.name = name
    }
}

var john: Person? = Person(name: "John")
var doe: Person? = Person(name: "Doe")

john?.bestFriend = doe

여기서는 bestFriend 속성이 약한 참조이므로, doe가 다른 곳에서 강하게 참조되지 않으면 메모리에서 해제될 수 있습니다.

미약 참조(Unowned Reference)

미약 참조는 약한 참조와 비슷하지만, 해제된 인스턴스를 참조할 때 nil이 되지 않으며 프로그램이 크래시됩니다. 미약 참조는 해제될 인스턴스가 확실히 존재하는 경우에 사용합니다. 예:

swift
class Customer {
    var name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
}

var john: Customer? = Customer(name: "John")
var card: CreditCard? = CreditCard(number: 1234_5678_9012_3456, customer: john!)

john?.card = card

여기서 CreditCard의 고객 참조는 미약 참조로, Customer 인스턴스가 CreditCard 인스턴스보다 오래 살아남는 것을 보장해야 합니다.

프로퍼티 Assign 방법

프로퍼티를 참조 타입으로 할당할 때, ARC를 이해하고 적절히 활용하는 것이 중요합니다. 예를 들어 프로퍼티가 강한 참조로 남아있으면 메모리 누수가 발생할 수 있습니다. 이 때문에 약한 참조와 미약 참조를 적절히 사용하여 강한 참조 순환을 방지해야 합니다. 이를 통해 안정적이고 효율적인 메모리 관리를 이룰 수 있습니다.

Swift의 프로퍼티 할당은 ARC를 이해하고 이를 적절히 활용하는 것이 중요합니다. 이를 통해 메모리 누수를 방지하고, 프로그램이 원하는 대로 작동할 수 있습니다. 인스턴스의 생명 주기를 고려하여 강한 참조, 약한 참조, 미약 참조를 적절히 배치하는 것은 프로페셔널 Swift 개발자가 갖추어야 할 필수적인 능력입니다.