ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS, Swift] Callback 함수와 Closure
    iOS/기본 원리 2023. 8. 30. 10:41
    반응형

    Callback 함수는 특정 작업이나 함수의 완료 이후에 실행되도록 설계된 프로그래밍 패턴을 가리킵니다.

     

    이러한 Callback 함수는 특히 비동기 작업에 많이 활용됩니다. 웹 요청 또는 파일 읽기와 같은 작업이 시작될 때, 이러한 함수에 callback을 전달하면 작업 완료 시 해당 callback 함수가 자동으로 호출되어, 결과를 처리하거나 발생한 오류를 관리합니다.

     

    Swift 언어에서는 이러한 Callback 기능을 구현하기 위해 Closure를 활용합니다.

     

    func fetchData(completion: (String) -> Void) {
        // 데이터를 비동기적으로 가져오는 가상의 코드
        DispatchQueue.global().async {
            let data = "데이터"
            
            // 메인 스레드에서 완료 핸들러를 호출
            DispatchQueue.main.async {
                completion(data)
            }
        }
    }
    
    fetchData { result in
        print("받아온 데이터: \(result)")
    }

     

    이 코드 예제에서는 completion 매개변수에 클로저를 전달하여, 메인 스레드에서 해당 클로저가 실행 될 수 있도록 합니다.

     

    순환 참조 문제

    클로저는 주변의 변수나 상수를 자동으로 캡쳐할 수 있는 특성이 있습니다. 이 때, 클래스 인스턴스를 참조하게 되면 순환 참조가 발생할 위험이 있습니다. 이러한 순환 참조가 발생하면, 관련된 객체들이 메모리에서 올바르게 해제되지 않아 메모리 누수를 유발하게 됩니다.

     

    class TaskManager {
        var taskName: String
        var completion: (() -> Void)?
        
        init(taskName: String) {
            self.taskName = taskName
        }
        
        func startTask() {
            // 클로저 내에서 self를 참조하면서 순환 참조 발생
            completion = {
                print("Task \(self.taskName) is completed!")
            }
        }
        
        deinit {
            print("\(taskName) is being deinitialized")
        }
    }
    
    var myTask: TaskManager? = TaskManager(taskName: "Download")
    myTask?.startTask()
    
    // 이후에 객체에 nil을 할당하여 deinitializer를 호출하려고 시도
    myTask = nil

     

    위 코드 예제에서 myTask 객체를 nil을 할당하려고 해도 참조 순환 문제 때문에 deinit 함수를 호출하지 못합니다.

     

    이러한 순환 참조를 피하기 위한 방법은 클로저 내에서 [weak self] 또는 [unowned self] 구문을 사용하는 것입니다. 이렇게 하면 클로저 내부에서 클래스 인스턴스에 대한 약한 참조나 비소유 참조를 생성하여 순환 참조 문제를 방지할 수 있습니다.

     

    [weak self]: self는 옵셔널로 취급됩니다. 인스턴스가 메모리에서 해제되면 self는 nil로 설정됩니다.

    [unowned self]: self는 옵셔널이 아닙니다. 인스턴스가 메모리에서 해제된 후에 self를 참조하면 런타임 오류가 발생합니다.

     

    반응형

    'iOS > 기본 원리' 카테고리의 다른 글

    [iOS, Swift] Optional 타입  (0) 2023.08.29
    [Swift, 패턴] SOLID에 대한 개념  (0) 2023.08.28
Designed by Tistory.