Зачем использовать протокол NSObject для реализации протокола
Я видел код, похожий на следующий:
@protocol MyProtocol <NSObject>
// write some methods.
@end
Есть ли какая-то конкретная причина, по которой MyProtocol соответствует протоколу NSObject? Разве это не слишком избыточно, если вы делаете что-то вроде:
id <MyProtocol> foo; // foo here conforms to NSObject AND MyProtocol?
Просто интересно, что такое логика.
Ответы
Ответ 1
Я уверен, что причина, по которой вы это сделаете, - добавить к вашему протоколу членов NSObject (например, сохранить и освободить). Технически вы все равно можете отправлять эти сообщения, но вы получите предупреждение компилятора без него.
Ответ 2
Когда вы объявляете переменную типа
id<MyProtocol> var;
компилятор Objective-C знает только о методах в MyProtocol
и, таким образом, выдает предупреждение, если вы попытаетесь вызвать любой из методов NSObject
, например -retain/-release
, в этом экземпляре. Таким образом, Cocoa определяет протокол NSObject
, который отражает методы класса и экземпляра NSObject
. Объявив, что MyProtocol
реализует протокол NSObject
, вы даете компилятору намек на то, что все методы NSObject
будут реализованы экземпляром, который реализует MyProtocol
.
Почему все это необходимо? Objective-C позволяет объектам спускаться из любого корневого класса. В Cocoa NSObject является наиболее распространенным, но не единственным корневым классом. NSProxy
также является корневым классом. Поэтому экземпляр типа id
не обязательно наследует методы NSObject
.
Ответ 3
Это также очень удобно, когда у вас есть протоколы с @optional
методами (например, "современные" Objective-C делегаты 2.0 часто используют этот метод). Если вы не включили протокол NSObject
, вы получите предупреждения, когда вы пытаетесь вызвать respondsToSelector:
на объект.
Ответ 4
Я никогда не делал этого в своем коде, но я мог видеть его преимущество. Если вы передадите параметр как id <SomeProtocol>
, вам нужно будет повторно его переслать, если вы хотите вызвать любой из методов NSObject на этом объекте.
Ответ 5
Если вы используете какой-либо из методов протокола NSObject, таких как сохранение, выпуск, класс, имя класса, компилятор предоставит вам предупреждения, если ваш протокол также не содержит протокол NSObject.