본문 바로가기
Swift

[Swift] deinitializer 활용

by giop15 2023. 10. 26.
반응형

이번에는 deinitializer가 사용되는 사례에 대해서 알아보려고 합니다.

 

[deinit]

deinit은 인스턴스가 메모리에서 해제되기 직전에 호출됩니다. 인스턴스를 해제하기 전에 선행되어야 하는 작업이 있다면 deinit에 구현할 수 있습니다.

 

deinit을 사용하여 파일 핸들을 관리하는 예시 코드를 살펴보겠습니다.

class FileHandler {
    let fileHandle: FileHandle

    init(filePath: String) {
        // 파일이 없으면 파일을 생성하고 파일 핸들을 엽니다.
        if !FileManager.default.fileExists(atPath: filePath) {
            FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
        }
        
        guard let handle = FileHandle(forWritingAtPath: filePath) else {
            fatalError("Failed to open the file.")
        }
        fileHandle = handle
    }

    func write(_ text: String) {
        // 파일에 데이터 쓰기
        if let data = text.data(using: .utf8) {
            fileHandle.write(data)
        }
    }

    deinit {
        // 클래스 인스턴스가 메모리에서 해제될 때 파일 핸들 닫기
        fileHandle.closeFile()
        print("FileHandler deinit")
    }
}

// FileHandler 인스턴스 생성
var fileHandler: FileHandler? = FileHandler(filePath: "example.txt")

// 파일에 데이터 쓰기
fileHandler?.write("Hello, World!")

// FileHandler 인스턴스 해제
fileHandler = nil

// FileHandler deinit

위의 코드에서 FileHandler 클래스는 파일을 열고 데이터를 쓰는 작업을 수행합니다. 클래스 인스턴스가 메모리에서 해제될 때 deinit 블록을 사용하여 파일 핸들을 안전하게 닫습니다.

 

두 번째로는 네트워크 연결을 관리하는 예시 코드를 살펴보겠습니다.

class NetworkClient {
    var serverURL: URL
    var session: URLSession?

    init(serverURL: URL) {
        self.serverURL = serverURL
        self.session = URLSession.shared
    }

    func fetchData(completion: @escaping (Result<data, error="">) -> Void) {
        let task = session?.dataTask(with: serverURL) { data, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            if let data = data {
                completion(.success(data))
            }
        }
        task?.resume()
    }

    deinit {
        // 클래스 인스턴스가 메모리에서 해제될 때 세션을 무효화하여 네트워크 연결 해제
        session?.finishTasksAndInvalidate()
        print("NetworkClient deinit")
    }
}

// 웹 서버 URL
let serverURL = URL(string: "<https://example.com/data>")!

// 네트워크 클라이언트 인스턴스 생성
var client: NetworkClient? = NetworkClient(serverURL: serverURL)

// 데이터 요청 및 처리
client?.fetchData { result in
    switch result {
    case .success(let data):
        let responseString = String(data: data, encoding: .utf8)
        print("Received data: \\(responseString ?? "N/A")")
    case .failure(let error):
        print("Error: \\(error)")
    }
}

// 네트워크 클라이언트 인스턴스 해제
client = nil

이 예제에서, NetworkClient 클래스는 HTTP GET 요청을 보내고 응답을 받아오는 간단한 네트워크 클라이언트를 나타냅니다. deinit 메서드에서는 URLSession의 finishTasksAndInvalidate() 메소드를 사용하여 네트워크 세션을 무효화하고 연결을 해제합니다.

이렇게 deinit를 활용하면 클래스 인스턴스가 메모리에서 해제될 때 네트워크 연결을 안전하게 종료할 수 있습니다.

 

지금까지 deinit을 사용하는 방법에 대해서 알아보았습니다.

반응형

'Swift' 카테고리의 다른 글

[Swift] 스위프트 메모리 관리  (1) 2023.10.26
[Swift] 클로저의 Escaping과 Capture List  (0) 2023.10.24
[Swift] 상수와 변수  (0) 2023.10.23