대답은 ... 음 ... 간단합니다. 사실 단순성과 일관성.
Objective-C는 메소드 디스패치 시점에서 순전히 동적입니다. 특히 모든 메서드 디스패치는 다른 모든 메서드 디스패치와 똑같은 동적 메서드 확인 지점을 거칩니다. 런타임시 모든 메서드 구현은 정확히 동일한 노출을 가지며 메서드 및 선택기와 함께 작동하는 Objective-C 런타임에서 제공하는 모든 API는 모든 메서드에서 동일하게 작동합니다.
많은 사람들이 대답했듯이 (여기와 다른 질문 모두에서), 컴파일 타임 프라이빗 메서드가 지원됩니다. 클래스가 공개적으로 사용 가능한 인터페이스에서 메서드를 선언하지 않으면 해당 메서드는 코드에 관한 한 존재하지 않을 수도 있습니다. 즉, 프로젝트를 적절하게 구성하여 컴파일 시간에 원하는 다양한 가시성 조합을 모두 얻을 수 있습니다.
동일한 기능을 런타임에 복제해도 이점이 거의 없습니다. 그것은 엄청난 양의 복잡성과 오버 헤드를 추가 할 것입니다. 그리고 그 모든 복잡성에도 불구하고 가장 평범한 개발자가 "개인"메서드를 실행하는 것을 막지는 못합니다.
편집 : 내가 알아 차린 가정 중 하나는 개인 메시지가 런타임을 거쳐야하므로 잠재적으로 큰 오버 헤드가 발생할 수 있다는 것입니다. 이것이 절대적으로 사실입니까?
네, 그렇습니다. 클래스의 구현자가 구현의 모든 Objective-C 기능 세트를 사용하지 않을 것이라고 가정 할 이유가 없으며 이는 동적 디스패치가 발생해야 함을 의미합니다. 그러나objc_msgSend()
컴파일러가 전용 메서드임을 알 수 있기 때문에 전용 메서드를의 특수 변형에 의해 디스패치 할 수없는 특별한 이유가 없습니다 . 즉, 이것은 Class
구조에 개인 전용 메소드 테이블을 추가하여 달성 할 수 있습니다 .
private 메서드가이 검사를 단락 시키거나 런타임을 건너 뛸 수있는 방법이 없습니까?
런타임을 건너 뛸 수는 없지만 런타임 이 반드시 private 메서드를 검사 할 필요는 없습니다 .
즉, 타사가 objc_msgSendPrivate()
해당 객체의 구현 외부에서 의도적으로 객체를 호출 할 수 없으며 일부 작업 (예 : KVO)이이를 수행해야 할 이유가 없습니다. 사실상, 그것은 단지 관례 일 뿐이며, 개인 메소드의 선택자를 접두사로 붙이거나 인터페이스 헤더에 언급하지 않는 것보다 실제로는 조금 더 낫습니다.
하지만 그렇게하는 것은 언어의 순수한 동적 특성을 훼손 할 것입니다. 더 이상 모든 메소드 디스패치가 동일한 디스패치 메커니즘을 거치지 않습니다. 대신 대부분의 방법이 한 방향으로 작동하고 소수는 다른 상황에 처하게됩니다.
이것은 Objective-C의 일관된 역 동성 위에 구축 된 Cocoa의 많은 메커니즘이 있기 때문에 런타임을 넘어 확장됩니다. 예를 들어, Key Value Coding과 Key Value Observation은 모두 개인 메서드를 지원하기 위해 매우 많이 수정해야합니다 (대부분 악용 가능한 허점을 생성하여). 그렇지 않으면 개인 메서드가 호환되지 않습니다.