Зачем привязывать протокол NSObject к реализации протокола - PullRequest
31 голосов
/ 25 марта 2009

Я видел какой-то код, похожий на следующий:

@protocol MyProtocol <NSObject>
// write some methods.
@end

Есть ли какая-либо конкретная причина, по которой MyProtocol соответствует протоколу NSObject? Разве это не избыточно, если вы делаете что-то вроде:

id <MyProtocol> foo; // foo here conforms to NSObject AND MyProtocol?

Просто любопытно, что такое логика.

Ответы [ 5 ]

31 голосов
/ 25 марта 2009

Когда вы объявляете переменную типа

 id<MyProtocol> var;

компилятор Objective-C знает только о методах в MyProtocol и, таким образом, выдаст предупреждение, если вы попытаетесь вызвать любой из NSObject методов, таких как -retain/-release, в этом экземпляре. Таким образом, Cocoa определяет протокол NSObject, который отражает класс NSObject и методы экземпляра. Объявляя, что MyProtocol реализует протокол NSObject, вы даете компилятору подсказку, что все методы NSObject будут реализованы экземпляром, который реализует MyProtocol.

Зачем все это необходимо? Objective-C позволяет объектам происходить из любого корневого класса. В Какао NSObject является наиболее распространенным, но не единственным корневым классом. Например, NSProxy также является корневым классом. Поэтому экземпляр типа id не обязательно обязательно наследует методы NSObject.

28 голосов
/ 25 марта 2009

Я почти уверен, что причина, по которой вы это сделаете, заключается в добавлении членов NSObject (скажем, как retain и release) в ваш протокол. Технически вы все равно можете отправлять эти сообщения, но без него вы получите предупреждение компилятора.

22 голосов
/ 25 марта 2009

Это также очень удобно, когда у вас есть протоколы, которые имеют методы @optional (например, "современные" делегаты Objective-C 2.0 часто используют этот метод). Если вы не включите протокол NSObject, вы получите предупреждения, когда вы пытаетесь вызвать respondsToSelector: на объекте.

2 голосов
/ 26 марта 2009

Если вы используете какие-либо методы протокола NSObject, такие как retain, release, class, classname, компилятор выдаст вам предупреждения, если ваш протокол также не включает протокол NSObject.

2 голосов
/ 25 марта 2009

Я никогда не делал этого в своем коде, но я видел преимущество в этом. Если вы передадите параметр как id <SomeProtocol>, вам нужно будет повторно привести его, если вы хотите вызвать любой из методов NSObject для этого объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...