2012-04-06 32 views
15

Giao thức NSObject đi kèm với các mẫu giao thức chứng khoán, nhưng nó dường như không phải là tất cả những gì cần thiết cho việc triển khai thực tế của giao thức. Để nó ra dường như thay đổi hoàn toàn không có gì. Vì vậy, nó thực sự cần thiết cho một giao thức để kế thừa từ nó, hoặc là nó chỉ là một add-on không cần thiết?Giao thức phải tuân thủ Giao thức NSObject?

Trả lời

19

Trong nhiều năm qua tôi (và nhiều như tôi) đã không thực hiện giao thức của chúng tôi tuân theo <NSObject>. Nó hoạt động tốt. Nhưng nó thường có thể gây phiền nhiễu. Khó chịu phổ biến nhất là bạn không thể sử dụng respondsToSelector: mà không cần quay lại NSObject* (loại đánh bại toàn bộ điểm của giao thức). Điều đó không quan trọng trong ObjC1 ngày vì không có @optional, vì vậy không ai trong số chúng tôi lo lắng về điều đó (chúng tôi đã không sử dụng giao thức nhiều trong những ngày đó kể từ khi không có @optional chúng không hữu ích). Sau đó, ObjC2 đi kèm với sự bổ sung tuyệt vời của các phương pháp tùy chọn và đột nhiên respondsToSelector: quan trọng. Phải mất một chút thời gian cho chúng tôi chậm hơn, nhưng cuối cùng chúng tôi bắt đầu tìm ra rằng cuộc sống đơn giản hơn nhiều nếu bạn thực hiện các giao thức của mình phù hợp với <NSObject>. May mắn thay, điều này đã được đưa vào Xcode, giúp mọi người dễ dàng làm mọi thứ theo cách thuận tiện hơn.

Nhưng không, bạn không phải làm điều đó. Nó không quan trọng trong nhiều trường hợp. Nhưng không có nhiều lý do để không làm điều đó, vì vậy tôi khuyên bạn nên làm điều đó.

+0

Câu trả lời tuyệt vời ... Nhưng ngay cả những phiền toái bạn đang đề cập đến với giao thức NSObject sẽ chỉ đi vào chơi với 'id obj', bởi vì nếu bạn tham chiếu đối tượng với một lớp, trình biên dịch sẽ biết thừa kế ... có lẽ bắt đầu với NSObject ... –

6

Không nhất thiết. Một đại biểu chỉ là một đối tượng trợ giúp - các yêu cầu duy nhất là những yêu cầu mà lớp ủy nhiệm đặt trên đó. Nếu bạn muốn chính thức hóa các yêu cầu cho một đại biểu cụ thể, hãy tạo một giao thức chính thức, tức là tuyên bố một giao thức bằng cách sử dụng chỉ thị @protocol. Nếu phù hợp với các giao thức NSObject là một trong những yêu cầu, bạn có thể làm cho giao thức bạn áp dụng nó:

@protocol MyDelegateProtocol <NSObject> 
//... 
@end 

Điều đó nói rằng, tôi không thấy bất kỳ lý do gì để tạo ra một đại biểu đó là không bắt nguồn từ NSObject hoặc có lẽ NSProxy, và cả hai lớp đó đều tuân theo giao thức NSObject.

+0

Đại biểu có thể bắt nguồn từ ngắt NSObject nếu giao thức không phù hợp với NSObject không? (nói cách khác, không phù hợp với nguyên nhân chung khiến phương pháp đại biểu không được gọi)? – CodaFi

+2

Vì NSObject tuân theo giao thức NSObject, bất kỳ lớp nào có nguồn gốc từ NSObject cũng tuân theo giao thức NSObject. Vì vậy, không có, một đại biểu có nguồn gốc từ NSObject sẽ không phá vỡ chỉ vì giao thức đại biểu mà nó thông qua không rõ ràng thông qua giao thức NSObject. – Caleb

1

Không phải mọi đối tượng đều phải phân lớp NSObject vì vậy tôi đoán nếu bạn đang mong đợi một đối tượng như vậy để phù hợp với giao thức của bạn, nó sẽ không nhất thiết phải phù hợp với NSObject.

Tuân thủ NSObject, hãy cho trình biên dịch biết rằng đối tượng tuân thủ các khái niệm cơ bản - kiểm tra xem nó ra NSObject Protocol Reference. Nếu không nói rằng tôi phù hợp với NSObject làm thế nào trình biên dịch biết tôi phù hợp với bất kỳ điều này?

NSObject được định nghĩa là

@interface NSObject <NSObject> { 
    Class isa; 
} 

trong khi id được định nghĩa là

typedef struct objc_object { 
    Class isa; 
} *id; 

Vì vậy, đối id trình biên dịch không biết nó tuân thủ để NSObject

1

Đề xuất và không bắt buộc.

Theo tài liệu chính thức của Apple ProgrammingWithObjectiveC.pdf

Nếu bạn cố gắng gọi phương thức respondsToSelector: trên một id phù hợp với các giao thức như nó được định nghĩa ở trên, bạn sẽ nhận được một lỗi biên dịch rằng không có phương pháp dụ cụ thể nào cho nó.Khi bạn đủ điều kiện một id có giao thức, việc kiểm tra loại allstatic sẽ trở lại; bạn sẽ nhận được lỗi nếu bạn cố gắng gọi bất kỳ phương thức nào không được xác định trong giao thức được chỉ định trong giao thức được chỉ định trong giao thức được chỉ định . Một cách để tránh lỗi trình biên dịch là đặt giao thức tùy chỉnh để áp dụng giao thức NSObject.

giao thức như được định nghĩa ở trên là giao thức mà không tuân thủ giao thức NSObject.

Như một ví dụ, đó là thực hành tốt nhất để xác định các giao thức của bạn cho phù hợp để giao thức NSObject (một số trong những hành vi NSObject được chia từ giao diện các lớp học vào một giao thức riêng biệt; lớp NSObject thông qua các Giao thức NSObject).

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