Tôi biết rằng khi chúng ta muốn tạo một đối tượng giá trị không xác định, chúng tôi sử dụng id. Tuy nhiên, tôi tò mò rằng tại sao Apple chọn id quyết định giá trị của nó trong thời gian chạy, khi mọi đối tượng là một lớp con của NSObject. Vì vậy, thay vì id delegate
chúng tôi có thể đã sử dụng NSObject *delegate
Có ai biết tại sao không? Cảm ơn.Tại sao nên sử dụng id khi chúng ta có thể sử dụng NSObject?
Trả lời
id
xóa loại và tương đương với việc nói "đối tượng này phản hồi với bất kỳ bộ chọn nào hiển thị với bản dịch". tất nhiên, đó là trách nhiệm của bạn để đảm bảo chương trình của bạn là chính xác khi bạn xóa các loại (và cũng có thể khi bạn nhập chúng).
Nếu loại là NSObject
, trình biên dịch sẽ nói "NSObject có thể không phản hồi bộ chọn" nếu bộ chọn không được khai báo trong giao diện của NSObject hoặc giao thức mà nó chấp nhận. Trong sự kiện đó, bạn cũng có thể thêm một typecast để đúc nó vào loại bạn mong đợi.
Với các loại nghiêm ngặt/chính xác, trình biên dịch có thể khởi động và giúp bạn, điều này rất tuyệt vì ObjC là một ngôn ngữ rất năng động.
id
đặc biệt hữu ích khi sử dụng (hoặc xây dựng) các loại bộ sưu tập. Thêm một đối tượng sẽ không là vấn đề trừ khi bạn đã định nghĩa một kiểu gốc mới (không thừa kế từ NSObject). Lấy một giá trị từ bộ sưu tập sẽ yêu cầu một typecast nếu chúng ta sử dụng nó như một cái gì đó khác với lớp cơ sở của chúng ta (NSObject).
Mục tiêu-C không hỗ trợ Generics - bạn không thể, ví dụ: khai báo số NSArray
trong số NSString
s. Bạn có thể điền một số NSArray
với NSString
s và chuyển số này qua id
để có phong cách viết tự nhiên hơn khi loại an toàn không được giữ nguyên (một la generics).
Vì vậy, hãy mở rộng điều này bằng một số mã thực.
Ví dụ A
NSString * string = [array objectAtIndex:0]; // << trust me (via id)
return [string length];
-or-
return [[array objectAtIndex:0] length]; // << trust me (via id)
Ví dụ B
Và bây giờ chúng ta hãy nói id
không có sẵn và chúng tôi sửa chữa tất cả các cảnh báo trình biên dịch của chúng tôi bởi vì đó là điều đúng đắn nên làm:
NSString * string = (NSString*)[array objectAtIndex:0]; // << typecast == trust me
return [string length];
-or-
return [(NSString*)[array objectAtIndex:0] length]; // << typecast == trust me
id
không quyết định giá trị của nó trong thời gian chạy, cũng không phải doe bất kỳ NSObject. Đối tượng ObjC không thực hiện các quảng cáo ngầm, chúng chỉ truyền con trỏ mà không cần quảng cáo chính thức.
liên quan đến ví dụ của bạn, tôi thực sự tuyên bố đại biểu và các thông số của tôi như NSObjects với các giao thức:
NSObject<MONShapeDelegate>* delegate;
Nó có thể khác với các trình biên dịch khác so với các trình biên dịch tôi đã sử dụng, nhưng theo như tôi biết, nếu bạn khai báo một kiểu như NSObject
@Aberrant nếu phương thức đại biểu là tùy chọn, tùy thuộc vào * người gọi * để xác minh đối tượng phản hồi với bộ chọn. – justin
Tôi biết, đó là lý do tại sao tôi nói trình biên dịch giả định chúng được triển khai. Nếu không, các tùy chọn sẽ luôn gây cảnh báo, vì trình biên dịch không thể chắc chắn nếu các đối tượng sẽ phản hồi khi chạy. – Aberrant
mọi đối tượng là một lớp con của NSObject
Đó không phải là chính xác. Bạn có thể làm cho một đối tượng kéo dài từ không có gì là một lớp gốc.
Đó có lẽ là lý do id được giới thiệu.
mọi đối tượng là một lớp con của NSObject
Đó là một tuyên bố không chính xác. Bạn có thể tạo các đối tượng không kế thừa từ NSObject. nó không thực sự được đề nghị, nhưng nó là có thể.
NSProxy
là một ví dụ - nó không được kế thừa từ NSObject.
Đây chỉ là bản sao câu trả lời của tôi! –
Xin lỗi:/Tôi đã viết nó khi không có câu trả lời, bạn đánh tôi đến cú đấm ... không có cảm giác khó khăn và không thực sự cần thiết cho một cuộc bỏ phiếu xuống ... Ngoài ra, bạn đã không đề cập đến 'NSProxy' ... – Jasarien
Nếu đó là ngăn xếp và câu trả lời này ở dưới cùng thì @Jasarien đã trả lời trước hết;) – beryllium
typedef struct objc_object {
Class isa;
} *id;
Trên đây là định nghĩa thực tế của id
trong ngôn ngữ mục tiêu-C. Hệ thống thời gian chạy Objective-C được xây dựng xung quanh id
và Class
. Không có gì phải làm với NSObject hoặc lớp siêu phổ biến.
Các NSObject Lớp
NSObject là một lớp rễ, và do đó không có một lớp cha. Nó định nghĩa khung cơ bản cho các đối tượng Objective-C và các tương tác đối tượng. Nó truyền đạt các lớp và các thể hiện của các lớp kế thừa từ nó khả năng hoạt động như các đối tượng và hợp tác với hệ thống thời gian chạy .
Lớp học không cần kế thừa bất kỳ hành vi đặc biệt nào từ lớp khác vẫn nên được tạo thành lớp con của lớp NSObject. Các trường hợp của lớp phải ít nhất có khả năng hoạt động như các đối tượng mục tiêu Mục tiêu-C khi chạy. Thừa kế khả năng này từ lớp NSObject đơn giản hơn nhiều và đáng tin cậy hơn nhiều so với việc phát minh lại nó trong định nghĩa lớp mới.
Tôi nghĩ, điều này là do ban đầu nó là C
không phải C++
(hoặc các ngôn ngữ nhập văn bản nghiêm ngặt hơn).
- 1. Tại sao chúng ta nên sử dụng mã hóa ui khi chúng ta có Specflow?
- 2. tại sao chúng ta không nên sử dụng ++ trong javascript?
- 3. Tại sao chúng ta sử dụng Response.ClearHeaders()?
- 4. Khi nào chúng ta nên sử dụng lớp học và khi chúng ta không nên
- 5. Khi nào chúng ta nên sử dụng mutex và khi nào chúng ta nên sử dụng semaphore
- 6. MVC: tại sao chúng ta cần "điều khiển", hoặc khi nào chúng ta nên sử dụng mẫu này?
- 7. Chúng ta có nên đóng HttpPostedFile.Inputstream, khi chúng ta đã hoàn thành việc sử dụng nó?
- 8. Khi nào và tại sao chúng ta nên sử dụng lớp System.ComponentModel.Container?
- 9. Chúng ta có nên sử dụng ScalaSignature trực tiếp không?
- 10. Tại sao chúng ta sử dụng giao diện thành viên?
- 11. Tại sao chúng ta sử dụng radian trong lập trình?
- 12. Tại sao chúng ta sử dụng chú thích ngủ đông?
- 13. Tại sao chúng ta sử dụng động Proxy
- 14. Tại sao chính xác chúng ta sử dụng NoSQL?
- 15. Tại sao chúng ta cần sử dụng cơ số?
- 16. chúng ta có thể sử dụng CASE với EXEC
- 17. Khi nào chúng ta sử dụng ANTLR
- 18. Tại sao chúng ta nên tránh sử dụng các biến lớp @@ trong đường ray?
- 19. Tại sao chúng ta nên sử dụng sp cho kích thước phông chữ trong Android?
- 20. Tại sao nên sử dụng mã hóa CJSON khi chúng tôi có json_encode
- 21. khi nào chúng ta nên sử dụng instanceof và khi không phải
- 22. Chúng ta có cần mfence khi sử dụng xchg
- 23. Tại sao tôi không nên sử dụng ID kiểu bằng cách sử dụng CSS?
- 24. chúng ta có thể sử dụng xpath với BeautifulSoup không?
- 25. Chúng ta có thể sử dụng pom.xml vào ANT
- 26. Khi nào chúng ta sẽ sử dụng applicationContext.xml trong Spring?
- 27. Tại sao chúng ta không thể sử dụng '==' để so sánh hai phao hoặc số đôi
- 28. Tại sao chúng ta không sử dụng toán tử mới khi khởi tạo một chuỗi?
- 29. Tại sao chúng ta không thể sử dụng C-strings như SELs?
- 30. Tôi có nên sử dụng FxCop và tại sao không?
NSProxy là một lớp gốc khác cung cấp cacao. –
NSObject chứa con trỏ isa, id không. Hãy xem http://stackoverflow.com/a/19634973/944634 –
những gì lol? id là một con trỏ isa. http://stackoverflow.com/questions/1990695/in-cocoa-how-is-the-id-type-defined – TheAmateurProgrammer