Swift. C부터 시작하는 메소드 디스패치

Introduction 메소드 호출이란 과연 무엇일까? 우리가 평소에 사용하는 메소드 호출은 내부적으로 어떻게 동작하는지 궁금해진 적이 있다. C++로 PS를 풀 때 가끔 함수 포인터를 써야 하는 경우가 생기는데, Swift에서 클로저를 이용하는 것과 비슷하지만 주변 값을 캡처할 수 없다는 특징이 있다. 함수 포인터는 C에도 존재하는 개념이므로, 다음과 같이 생각이 뻗어나갔다. 함수 포인터와 C 스타일 스트럭처를 사용하면 C언어에서도 OOP 스타일의 메소드가 구현 가능할 것 같다. 생각이 계속 확장되다 보니 실제 OOP 언어의 클래스 구현도 이런 방식으로 되어있지 않을까? 라는 생각에 도달했고, 메소드 디스패치를 포함해서 여러 개념들을 이어서 생각해볼 수 있었다. ...

May 31, 2025

Swift. 프로토콜 요구사항과 메소드 어트리뷰트

RemoteDBRequestBuildable 프로토콜을 추가한 뒤, 이전에는 나타나지 않던 unused-result 경고가 발생했다. 구체 타입에서는 사라졌던 경고 기존 구현의 request()에는 @discardableResult가 붙어 있었다. 반환값을 사용하지 않아도 경고가 발생하지 않았다. final class SupabaseDBRequestBuilder { @discardableResult func request() async throws -> Data { Data() } } let concrete = SupabaseDBRequestBuilder() try await concrete.request() 이후 Builder를 프로토콜로 추상화했지만 프로토콜 요구사항에는 해당 어트리뷰트를 붙이지 않았다. protocol RemoteDBRequestBuildable { func request() async throws -> Data } extension SupabaseDBRequestBuilder: RemoteDBRequestBuildable {} let abstract: any RemoteDBRequestBuildable = SupabaseDBRequestBuilder() try await abstract.request() 구체 구현에는 여전히 @discardableResult가 있는데도, 프로토콜 타입으로 호출하면 경고가 다시 나타났다. 호출을 검사하는 선언과 실행할 구현 컴파일러는 호출 지점의 정적 타입을 기준으로 사용할 메서드 선언을 해석한다. ...

February 10, 2025