2011-12-23 31 views
29

Tôi đã thực hiện một số tìm kiếm nhanh và không thể tìm thấy câu trả lời cho điều này.Trong Objective-C tại sao id được sử dụng làm kiểu trả về cho các phương thức init?

Tôi muốn biết tại sao trong Mục tiêu-C, id được sử dụng làm loại trả về cho phương thức init.

Tôi đoán là vì nếu lớp bị ghi đè, bạn không muốn trả lại đối tượng thuộc loại của lớp cha, nhưng tôi muốn biết liệu nó có được thực hiện vì một lý do nào khác không.

+7

Kính gửi người đó đã bình chọn câu hỏi này khoảng 7 giờ trước, nếu bạn định downvote một câu hỏi, dựa trên số lượng upvotes và yêu thích, rõ ràng đã giúp nhiều người hiểu về Objective-C, , ít nhất thêm một bình luận là tại sao ... –

Trả lời

19

Yup. Ý tưởng của bạn là đúng về tiền. Một lớp con sẽ vẫn có thể sử dụng các phương thức khởi tạo của lớp cha của nó và trả về kiểu riêng của nó thay vì kiểu siêu và trả lại id cho phép nó làm điều đó.

+10

Đọc liên quan: Clang đã giới thiệu một từ khóa mới, 'instancetype' giúp kiểm tra kiểu có thể trong khi vẫn giữ được tính năng kế thừa này trên các phương thức khác với 'init'. Xem [Nó sẽ có lợi khi bắt đầu sử dụng instancetype thay vì id?] (Http://stackoverflow.com/q/8972221) –

2

có thể để init thực sự trả lại phiên bản của một lớp khác, vì vậy, id được sử dụng. không thể nói rằng tôi đã từng thấy điều này xảy ra trong thực tế, nhưng hey :)

+7

Bạn đang sử dụng nó trong thực tế mọi lúc: 'NSArray' /' NSMutableArray', 'NSString' /' NSMutableString'. –

+0

điểm tốt! đã không nghĩ về nó theo cách đó –

+1

@JoshCaswell Sau đó, tại sao không làm cho nó trở lại một NSArray * thay vì id? Đa hình vẫn hợp lệ. –

5

Các loại ý tưởng lớp cha, trong khi một lý thuyết tốt, không thực sự đứng dậy: Một NSString * một NSObject *. Không có lý do gì nó không thể được gọi là như vậy.

Thay vào đó, tôi nghĩ rằng nó có nhiều việc phải làm với chữ ký chức năng. Trong một ngôn ngữ động như Objective-C, bạn không thể biết bạn đang nhắn tin với lớp nào. Nhưng trình biên dịch phải biết loại nào đang được trả về. Lịch sử của chương trình dựa trên quy ước và mục tiêu đó (thay vì có quy tắc nghiêm ngặt) có nghĩa là lớp con của bạn có thể trả lại NSRect (a struct) hoặc NSInteger (vô hướng) từ init. Đó là kooky, nhưng hợp lệ.

C++ có vấn đề tương tự, xem Is the return type part of the function signature?. Vì vậy, chúng tôi cần một loại duy nhất cho tất cả các phương pháp có chữ ký là -(id)initid là điều duy nhất có ý nghĩa vì nó chỉ quy định loại trả về là một cá thể. Đó là đủ cho trình biên dịch để làm điều đúng. Bây giờ chúng tôi có instancetype, phù hợp với lớp học được nhắn tin.

+0

Đó là một điểm tốt. –

+0

Cảm ơn. Xin lỗi vì sự necromancy ở đây; Tôi đến đây như là kết quả của thanh bên liên quan. :) –

+0

Không phải lo lắng, thông tin chi tiết bổ sung luôn được chào đón. Tôi đăng câu hỏi này ra khỏi tò mò hơn bất cứ điều gì. –

3

Trong thời gian chờ đợi, Apple đã thêm một cách mới để khai báo kiểu trả về của phương thức init.

Đó là instancetype. Đọc thêm về nó, ví dụ: here

+0

Như tôi đã hiểu, Clang thực sự tự động xử lý id như instancetype nội bộ cho các phương thức init (tôi không nghĩ rằng nó cho các phương thức tiện lợi lớp) –

Các vấn đề liên quan