Câu trả lời là ... à ... đơn giản. Đơn giản và nhất quán, trên thực tế.
Objective-C hoàn toàn năng động tại thời điểm gửi phương thức. Cụ thể, mọi công văn phương thức đều đi qua điểm phân giải phương thức động chính xác giống như mọi công văn phương thức khác. Trong thời gian chạy, mọi triển khai phương thức đều có cùng độ phơi sáng và tất cả các API được cung cấp bởi thời gian chạy Objective-C hoạt động với các phương thức và bộ chọn hoạt động như nhau trên tất cả các phương thức.
Như nhiều người đã trả lời (cả ở đây và trong các câu hỏi khác), các phương thức riêng thời gian biên dịch được hỗ trợ; nếu một lớp không khai báo một phương thức trong giao diện có sẵn công khai của nó, thì phương thức đó có thể không tồn tại xa như mã của bạn có liên quan. Nói cách khác, bạn có thể đạt được tất cả các kết hợp khả năng hiển thị khác nhau mong muốn tại thời điểm biên dịch bằng cách tổ chức dự án của bạn một cách thích hợp.
Có rất ít lợi ích để sao chép cùng chức năng vào thời gian chạy. Nó sẽ thêm một số lượng lớn phức tạp và chi phí chung. Và ngay cả với tất cả sự phức tạp đó, nó vẫn không thể ngăn chặn tất cả trừ nhà phát triển bình thường nhất thực hiện các phương thức được cho là "riêng tư" của bạn.
EDIT: Một trong những giả định mà tôi nhận thấy là các tin nhắn riêng tư sẽ phải trải qua thời gian chạy dẫn đến chi phí rất lớn. Điều này hoàn toàn đúng?
Vâng, đúng vậy. Không có lý do nào để giả sử rằng người triển khai một lớp sẽ không muốn sử dụng tất cả các tính năng Objective-C được thiết lập trong triển khai và điều đó có nghĩa là việc gửi động phải xảy ra. Tuy nhiên , không có lý do cụ thể tại sao các phương thức riêng tư không thể được gửi bởi một biến thể đặc biệt objc_msgSend()
, vì trình biên dịch sẽ biết rằng chúng là riêng tư; tức là điều này có thể đạt được bằng cách thêm một bảng phương thức chỉ riêng vào Class
cấu trúc.
Sẽ không có cách nào để một phương thức riêng tư làm ngắn mạch kiểm tra này hoặc bỏ qua thời gian chạy?
Nó không thể bỏ qua thời gian chạy, nhưng thời gian chạy không nhất thiết phải thực hiện bất kỳ kiểm tra nào cho các phương thức riêng tư.
Điều đó nói rằng, không có lý do gì mà bên thứ ba không thể cố tình kêu gọi objc_msgSendPrivate()
một đối tượng, ngoài việc thực hiện đối tượng đó và một số điều (ví dụ KVO) sẽ phải làm điều đó. Trên thực tế, nó sẽ chỉ là một quy ước và tốt hơn một chút trong thực tế so với các bộ chọn tiền tố của các phương thức riêng tư hoặc không đề cập đến chúng trong tiêu đề giao diện.
Tuy nhiên, để làm như vậy, sẽ làm suy yếu bản chất năng động thuần túy của ngôn ngữ. Không còn mọi phương thức gửi đi thông qua một cơ chế công văn giống hệt nhau. Thay vào đó, bạn sẽ bị bỏ lại trong một tình huống mà hầu hết các phương thức hành xử theo một cách và một số ít chỉ khác nhau.
Điều này mở rộng ra ngoài thời gian chạy vì có nhiều cơ chế trong Ca cao được xây dựng dựa trên tính năng động nhất quán của Objective-C. Ví dụ, cả Mã hóa giá trị khóa và Quan sát giá trị khóa sẽ phải được sửa đổi rất nhiều để hỗ trợ các phương thức riêng tư - rất có thể bằng cách tạo lỗ hổng có thể khai thác - hoặc các phương thức riêng tư sẽ không tương thích.