Instancetype vs имя класса для singleton?
Из того, что я понимаю, instancetype объявляет компилятору, что возвращаемый тип метода такой же, как класс, получающий сообщение.
Традиционно я всегда объявлял свои инициализаторы singleton с именем класса, явно заданным как возвращаемый тип:
@interface MyClass : NSObject
+ (MyClass *)sharedInstance;
@end
Теперь мне интересно, нужно ли вместо этого использовать instancetype:
@interface MyClass : NSObject
+ (instancetype)sharedInstance;
@end
В итоге результат тот же, мне просто интересно, есть ли причина использовать один или другой здесь?
Ответы
Ответ 1
instancetype
полезен для ситуаций, связанных с наследованием. У вас есть класс A
, который наследует от класса B
. Метод в B
, который возвращает экземпляр B
, может быть объявлен ранее как id
, его переопределение в A
может возвращать экземпляр A
- все это хорошо, но компилятор не имеет понятия. Однако, используя тип экземпляра, компилятору сообщают, что при вызове экземпляра A
, который метод возвращает экземпляр A
, и поэтому может дать лучшую диагностику, завершение кода и т.д.
Теперь в вашем примере вы использовали MyClass *
, а не id
, поэтому вы уже сказали компилятору тип. У вас также есть модель общего экземпляра (не одна модель, как вы можете использовать другие экземпляры MyClass
), вероятно, вы определите другой класс, который наследует от MyClass
и переопределяет метод sharedInstance
? Наверное, нет, но если вы делаете instancetype
, может быть полезно, иначе ничего не получится.
Ответ 2
Конструкторские методы традиционно возвращают id
, что позволяет подклассам также использовать их.
id
, конечно, означает "любой объект вообще". instancetype
, чтобы придать результат метода конструктора немного более строгой строгости.
Это полезно только в случае подкласса. Если этот метод никогда не будет переопределен, лучше быть максимально явным и использовать фактическое имя класса.