ios font Должны ли протоколы соответствовать протоколу NSObject?



swift set title text attributes (4)

Не обязательно. Делегат - это просто вспомогательный объект - единственными требованиями являются те, которые ему назначает делегирующий класс. Если вы хотите формализовать требования для данного делегата, создайте формальный протокол, то есть объявите протокол с @protocol директивы @protocol . Если соответствие протоколу NSObject является одним из этих требований, вы можете заставить свой протокол принять его:

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

Тем не менее, я не вижу причин для создания делегата, который не является производным от NSObject или, возможно, NSProxy, и оба эти класса уже соответствуют протоколу NSObject.

Протокол NSObject поставляется с шаблонами стандартных протоколов, но, похоже, он не является тем, что необходимо для реальной реализации протокола. Выход из этого, кажется, ничего не меняет. Итак, действительно ли необходимо, чтобы протокол наследовался от него, или это просто ненужное дополнение?


Answer #1

Не каждый объект должен иметь подкласс NSObject поэтому я предполагаю, что если вы ожидаете, что такой объект будет соответствовать вашему протоколу, он не обязательно должен соответствовать NSObject.

В соответствии с NSObject дайте компилятору понять, что объект соответствует основам - посмотрите его в NSObject Protocol Reference . Не говоря о том, что я соответствую NSObject, откуда компилятор узнает, что я соответствую всем этим?

NSObject определяется как

@interface NSObject <NSObject> {
    Class   isa;
}

тогда как id определяется как

typedef struct objc_object {
    Class isa;
} *id;

Таким образом, для id компилятор не знает, что он соответствует NSObject


Answer #2

В течение многих лет я (и многие, как я) не приводили наши протоколы в соответствие с <NSObject> . Работает нормально. Но это часто может раздражать. Наиболее распространенным раздражением является то, что вы не можете использовать respondsToSelector: без приведения обратно к NSObject* (который побеждает весь смысл протокола). В дни ObjC1 это не имело значения, потому что не было @optional , поэтому никто из нас не волновался об этом (в те дни мы вообще не пользовались протоколами, так как без @optional они были бы не так полезны). Затем появился ObjC2 с замечательным добавлением дополнительных методов и неожиданно откликнулся ToSelector respondsToSelector: значение. Для более медленных из нас это заняло некоторое время, но в конце концов мы начали понимать, что жизнь станет намного проще, если вы сделаете свои протоколы соответствующими <NSObject> . К счастью, теперь это проникло в XCode, упрощая всем возможность делать вещи более удобным способом.

Но нет, ты не обязан это делать. Это не имеет значения во многих случаях. Но нет особых причин не делать этого, поэтому я рекомендую это сделать.


Answer #3

Рекомендовать и не обязательно.

Согласно официальному документу Apple, ProgrammingWithObjectiveC.pdf

Если вы попытаетесь вызвать respondsToSelector: метод для идентификатора, соответствующего протоколу, как он определен выше, вы получите ошибку компилятора, что для него нет известного метода экземпляра. Как только вы квалифицируете идентификатор с помощью протокола, возвращается полная проверка типов; вы получите ошибку, если попытаетесь вызвать любой метод, который не определен в указанном протоколе. Один из способов избежать ошибки компилятора - установить собственный протокол для принятия протокола NSObject.

протокол, как он определен выше, является протоколом, не соответствующим протоколу NSObject .

Например, рекомендуется определить ваши протоколы в соответствии с протоколом NSObject (часть поведения NSObject разделяется от интерфейса его класса на отдельный протокол; класс NSObject принимает протокол NSObject).





nsobject